package mango.web.server.admin;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.ServletContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.supercsv.cellprocessor.ConvertNullTo;
import org.supercsv.cellprocessor.ift.CellProcessor;
import org.supercsv.io.CsvBeanReader;
import org.supercsv.io.CsvListWriter;
import org.supercsv.prefs.CsvPreference;

import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.datepicker.client.CalendarUtil;

import mango.web.client.C;
import mango.web.client.admin.AdminSearchVo;
import mango.web.client.admin.AdminViewI;
import mango.web.client.admin.ContactVo;
import mango.web.client.admin.EmailVo;
import mango.web.client.admin.EmailContentVo;
import mango.web.client.admin.FlowerChartVo;
import mango.web.client.admin.FlowerVo;
import mango.web.client.admin.LoginVo;
import mango.web.client.admin.LookupTVo;
import mango.web.client.admin.MemberPropertyVo;
import mango.web.client.admin.MemberVo;
import mango.web.client.admin.OrchardVo;
import mango.web.client.admin.RegionVo;
import mango.web.client.admin.SmsContentVo;
import mango.web.client.admin.TemperatureUrlVo;
import mango.web.client.admin.TemperatureVo;
import mango.web.client.admin.TreeVo;
import mango.web.client.admin.VarietyVo;
import mango.web.client.admin.XYDateDoubleVo;
import mango.web.server.Log;
import mango.web.server.Property;
import mango.web.server.ViewS;

@SuppressWarnings("serial")
public class AdminViewS extends ViewS implements AdminViewI {

	public List<String> getMemberIdList(AdminSearchVo adminSearchVo) {
		List<String> memberIdList = new ArrayList<String>();
		try {
			String sql = "";
			QueryRunner run = this.newQueryRunner();

			if (adminSearchVo != null) {
				StringBuffer where = new StringBuffer("");

				// TODO:Member
				if (!this.isEmpty(adminSearchVo.memberId)) where.append(" AND Member.memberId like '").append(adminSearchVo.memberId).append("'");
				if (!this.isEmpty(adminSearchVo.businessName)) where.append(" AND Member.businessName like '%").append(adminSearchVo.businessName).append("%'");
				if (!this.isEmpty(adminSearchVo.abn)) where.append(" AND Member.abn like '%").append(adminSearchVo.abn).append("%'");
				if (!this.isEmpty(adminSearchVo.businessType)) {
					String arr[] = adminSearchVo.businessType.split("&&");
					for (int i = 0; i < arr.length; i++) {
						String str = arr[i];
						if ("".equals(str)) continue;
						str += "&&";
						where.append(" AND Member.businessType like '%").append(str).append("%'");
					}
				}
				if (!this.isEmpty(adminSearchVo.other)) where.append(" AND Member.other like '%").append(adminSearchVo.other).append("%'");
				if (!this.isEmpty(adminSearchVo.membershipType)) where.append(" AND Member.membershipType like '").append(adminSearchVo.membershipType).append("'");
				if (!this.isEmpty(adminSearchVo.financialMember)) where.append(" AND Member.financialMember like '").append(adminSearchVo.financialMember).append("'");
				if (!this.isEmpty(adminSearchVo.annualReport)) where.append(" AND Member.annualReport like '").append(adminSearchVo.annualReport).append("'");
				//if (!this.isEmpty(adminSearchVo.authorisedContact)) where.append(" AND Member.authorisedContact like '%").append(adminSearchVo.authorisedContact).append("%'");
				if (!this.isEmpty(adminSearchVo.marketingGroupUsed)) where.append(" AND Member.marketingGroupUsed like '").append(adminSearchVo.marketingGroupUsed).append("'");
				if (!this.isEmpty(adminSearchVo.packsOwnProduce)) where.append(" AND Member.packsOwnProduce like '").append(adminSearchVo.packsOwnProduce).append("'");
				if (!this.isEmpty(adminSearchVo.marketGroup)) where.append(" AND Member.marketGroup like '%").append(adminSearchVo.marketGroup).append("%'");
				if (!this.isEmpty(adminSearchVo.brand)) where.append(" AND Member.brand like '%").append(adminSearchVo.brand).append("%'");
				// if (!"".equals(where.toString())) {
				sql = "SELECT Member.memberId FROM Member WHERE Member." + adminSearchVo.sqlStatus() + where.toString() + " ORDER BY Member.MemberId DESC";
				System.out.println(sql);
				memberIdList = run.query(sql, new ResultSetHandler<List<String>>() {

					public List<String> handle(ResultSet rs) throws SQLException {
						List<String> result = new ArrayList<String>();
						while (rs.next()) {
							String memberId = rs.getString("memberId");
							result.add(memberId);
						}
						return result;
					}

				});
				// }

				// TODO:Contact
				where = new StringBuffer("");
				if (!this.isEmpty(adminSearchVo.contactId)) where.append(" AND Contact.contactId like '").append(adminSearchVo.contactId).append("'");
				if (!this.isEmpty(adminSearchVo.firstname)) where.append(" AND Contact.firstname like '%").append(adminSearchVo.firstname).append("%'");
				if (!this.isEmpty(adminSearchVo.surname)) where.append(" AND Contact.surname like '%").append(adminSearchVo.surname).append("%'");
				if (!this.isEmpty(adminSearchVo.BHPhone)) where.append(" AND Contact.BHPhone like '%").append(adminSearchVo.BHPhone).append("%'");
				if (!this.isEmpty(adminSearchVo.AHPhone)) where.append(" AND Contact.AHPhone like '%").append(adminSearchVo.AHPhone).append("%'");
				if (!this.isEmpty(adminSearchVo.fax)) where.append(" AND Contact.fax like '%").append(adminSearchVo.fax).append("%'");
				if (!this.isEmpty(adminSearchVo.identifier)) where.append(" AND Contact.identifier like '%").append(adminSearchVo.identifier).append("%'");
				if (!this.isEmpty(adminSearchVo.mobile)) where.append(" AND Contact.mobile like '%").append(adminSearchVo.mobile).append("%'");
				if (!this.isEmpty(adminSearchVo.email)) where.append(" AND Contact.email like '%").append(adminSearchVo.email).append("%'");
				if (!this.isEmpty(adminSearchVo.service)) {
					String arr[] = adminSearchVo.service.split("&&");
					for (int i = 0; i < arr.length; i++) {
						String str = arr[i];
						if ("".equals(str)) continue;
						str += "&&";
						where.append(" AND Contact.service like '%").append(str).append("%'");
					}
				}
				if (!this.isEmpty(adminSearchVo.businessStreet)) where.append(" AND Contact.businessStreet like '%").append(adminSearchVo.businessStreet).append("%'");
				if (!this.isEmpty(adminSearchVo.businessCity)) where.append(" AND Contact.businessCity like '%").append(adminSearchVo.businessCity).append("%'");
				if (!this.isEmpty(adminSearchVo.businessState)) where.append(" AND Contact.businessState like '%").append(adminSearchVo.businessState).append("%'");
				if (!this.isEmpty(adminSearchVo.businessCountry)) where.append(" AND Contact.businessCountry like '%").append(adminSearchVo.businessCountry).append("%'");
				//\\if (!this.isEmpty(adminSearchVo.businessPostCode)) where.append(" AND Contact.businessPostCode like '%").append(adminSearchVo.businessPostCode).append("%'");
				if (!this.isEmpty(adminSearchVo.businessPostCode)) where.append(" AND (0+Contact.businessPostCode) ").append(adminSearchVo.sqlRange(adminSearchVo.businessPostCode));
				if (!this.isEmpty(adminSearchVo.postalStreet)) where.append(" AND Contact.postalStreet like '%").append(adminSearchVo.postalStreet).append("%'");
				if (!this.isEmpty(adminSearchVo.postalCity)) where.append(" AND Contact.postalCity like '%").append(adminSearchVo.postalCity).append("%'");
				if (!this.isEmpty(adminSearchVo.postalState)) where.append(" AND Contact.postalState like '%").append(adminSearchVo.postalState).append("%'");
				if (!this.isEmpty(adminSearchVo.postalCountry)) where.append(" AND Contact.postalCountry like '%").append(adminSearchVo.postalCountry).append("%'");
				//\\if (!this.isEmpty(adminSearchVo.postalPostCode)) where.append(" AND Contact.postalPostCode like '%").append(adminSearchVo.postalPostCode).append("%'");
				if (!this.isEmpty(adminSearchVo.postalPostCode)) where.append(" AND (0+Contact.postalPostCode) ").append(adminSearchVo.sqlRange(adminSearchVo.postalPostCode));
				Map<String, String> contactMap = null;
				List<ContactVo> contactList = null;
				if (!"".equals(where.toString())) {
					sql = "SELECT Contact.memberId FROM Contact WHERE 1=1" + where.toString();
					System.out.println(sql);
					contactMap = run.query(sql, new ResultSetHandler<Map<String, String>>() {

						public Map<String, String> handle(ResultSet rs) throws SQLException {
							Map<String, String> result = new HashMap<String, String>();
							while (rs.next()) {
								String memberId = rs.getString("memberId");
								result.put(memberId, memberId);
							}
							return result;
						}

					});
				}

				//if (adminSearchVo.appended == true) {
				sql = "SELECT Contact.contactId, Contact.memberId FROM Contact WHERE 1=1" + where.toString() + " ORDER BY Contact.MemberId,Contact.contactId DESC";
				contactList = run.query(sql, new ResultSetHandler<List<ContactVo>>() {

					public List<ContactVo> handle(ResultSet rs) throws SQLException {
						List<ContactVo> result = new ArrayList<ContactVo>();
						while (rs.next()) {
							ContactVo contact = new ContactVo();
							contact.contactId = (Integer) rs.getObject("contactId");
							contact.memberId = (Integer) rs.getObject("memberId");
							result.add(contact);
						}
						return result;
					}

				});
				//}

				if (contactList == null) contactList = new ArrayList<ContactVo>();

				// TODO:Orchard
				where = new StringBuffer("");
				// public String orchardId;
				if (!this.isEmpty(adminSearchVo.physicalLocation)) where.append(" AND Orchard.physicalLocation like '%").append(adminSearchVo.physicalLocation).append("%'");
				//\\if (!this.isEmpty(adminSearchVo.postCode)) where.append(" AND Orchard.postCode like '%").append(adminSearchVo.postCode).append("%'");
				if (!this.isEmpty(adminSearchVo.postCode)) where.append(" AND (0+Orchard.postCode) ").append(adminSearchVo.sqlRange(adminSearchVo.postCode));
				if (!this.isEmpty(adminSearchVo.state)) where.append(" AND Orchard.state like '%").append(adminSearchVo.state).append("%'");
				Map<String, String> orchardMap = null;
				if (!"".equals(where.toString())) {
					sql = "SELECT Orchard.memberId FROM Orchard WHERE 1=1" + where.toString();
					System.out.println(sql);
					orchardMap = run.query(sql, new ResultSetHandler<Map<String, String>>() {

						public Map<String, String> handle(ResultSet rs) throws SQLException {
							Map<String, String> result = new HashMap<String, String>();
							while (rs.next()) {
								String memberId = rs.getString("memberId");
								result.put(memberId, memberId);
							}
							return result;
						}

					});
				}

				// TODO:Tree
				where = new StringBuffer("");
				// public Integer treeId;
				//\\if (!this.isEmpty(adminSearchVo.yearPlanting)) where.append(" AND yearPlanting like '%").append(adminSearchVo.yearPlanting).append("%'");
				if (!this.isEmpty(adminSearchVo.yearPlanting)) where.append(" AND (0+yearPlanting) ").append(adminSearchVo.sqlRange(adminSearchVo.yearPlanting));
				if (!this.isEmpty(adminSearchVo.varietyId)) where.append(" AND varietyId like '").append(adminSearchVo.varietyId).append("'");
				// public String DTR;
				// public String BTR;
				// public String area;
				// public String areaType;
				if (!this.isEmpty(adminSearchVo.tree)) where.append(" AND tree ").append(adminSearchVo.sqlRange(adminSearchVo.tree));
				StringBuffer having = new StringBuffer("");
				if (!this.isEmpty(adminSearchVo.treeTotal)) having.append(" HAVING SUM(Tree.tree) ").append(adminSearchVo.sqlRange(adminSearchVo.treeTotal));
				// add
				//if (!this.isEmpty(adminSearchVo.treeTotal)) where.append(" AND 1=1");
				//final AdminSearchVo _adminSearchVo = adminSearchVo;
				Map<String, String> treeMap = null;
				if (!"".equals(where.toString()) || !"".equals(having.toString())) {
					sql = "SELECT Orchard.memberId FROM Tree, Orchard WHERE Tree.orchardId = Orchard.orchardId AND 1=1" + where.toString() + " GROUP BY Orchard.memberId" + having.toString();
					System.out.println(sql);
					try {
						treeMap = run.query(sql, new ResultSetHandler<Map<String, String>>() {

							public Map<String, String> handle(ResultSet rs) throws SQLException {
								Map<String, String> result = new HashMap<String, String>();
								while (rs.next()) {
									String memberId = rs.getString("memberId");
									/*
									if (!new ViewS().isEmpty(_adminSearchVo.treeTotal)) {
										String totalTree = rs.getString("totalTree");
										if (_adminSearchVo.treeTotal.trim().equals(totalTree)) {
											result.put(memberId, memberId);
										}
									} else {
									*/
									result.put(memberId, memberId);
									//}
								}
								return result;
							}

						});
					} catch (Exception ex) {
						treeMap = new HashMap<String, String>();
					}
				}

				for (int i = memberIdList.size() - 1; i >= 0; i--) {
					String memberId = memberIdList.get(i);
					if ((contactMap != null && contactMap.get(memberId) == null) || (orchardMap != null && orchardMap.get(memberId) == null) || (treeMap != null && treeMap.get(memberId) == null)) {
						memberIdList.remove(i);
					}
				}

				List<String> contactIdList = new ArrayList<String>();

				
				for (int i = 0; i < memberIdList.size(); i++) {
					String memberId = memberIdList.get(i);
					if (!adminSearchVo.memberIdList.contains(memberId)) {
						adminSearchVo.memberIdList.add(memberId);
					}
				}
				memberIdList = adminSearchVo.memberIdList;
				
				for (int i = contactList.size() - 1; i >= 0; i--) {
					ContactVo contactVo = contactList.get(i);
					if (!memberIdList.contains(contactVo.memberId + "")) {
						contactList.remove(i);
					} else {
						contactIdList.add(contactVo.contactId + "");
					}
				}
				if (adminSearchVo.appended == true) {
					for (int i = 0; i < contactIdList.size(); i++) {
						String contactId = contactIdList.get(i);
						if (!adminSearchVo.contactIdList.contains(contactId)) {
							adminSearchVo.contactIdList.add(contactId);
						}
					}
					contactIdList = adminSearchVo.contactIdList;
				}
				adminSearchVo.memberIdList = memberIdList;
				adminSearchVo.contactIdList = contactIdList;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}

		return adminSearchVo.memberIdList;
	}

	public MemberVo getMember(ResultSet rs) throws SQLException {
		MemberVo member = new MemberVo();
		member.memberId = (Integer) rs.getObject("memberId");
		member.businessName = rs.getString("businessName");
		member.abn = rs.getString("abn");
		member.businessType = rs.getString("businessType");
		member.other = rs.getString("other");
		member.membershipType = rs.getString("membershipType");
		member.financialMember = rs.getString("financialMember");
		member.annualReport = rs.getString("annualReport");
		member.authorisedContact = (Integer) rs.getObject("authorisedContact");
		member.marketingGroupUsed = rs.getString("marketingGroupUsed");
		member.packsOwnProduce = rs.getString("packsOwnProduce");
		member.marketGroup = rs.getString("marketGroup");
		member.brand = rs.getString("brand");
		member.status = rs.getString("status");
		return member;
	}

	public MemberVo getMember(String memberId) {
		MemberVo member = null;
		try {
			String sql = "SELECT * FROM Member WHERE memberId=" + memberId;
			QueryRunner run = this.newQueryRunner();
			member = run.query(sql, new ResultSetHandler<MemberVo>() {
				public MemberVo handle(ResultSet rs) throws SQLException {
					MemberVo member = null;
					while (rs.next()) {
						/*
						member = new MemberVo();
						member.memberId = (Integer) rs.getObject("memberId");
						member.businessName = rs.getString("businessName");
						member.abn = rs.getString("abn");
						member.businessType = rs.getString("businessType");
						member.other = rs.getString("other");
						member.membershipType = rs.getString("membershipType");
						member.financialMember = rs.getString("financialMember");
						member.annualReport = rs.getString("annualReport");
						member.authorisedContact = (Integer) rs.getObject("authorisedContact");
						member.marketingGroupUsed = rs.getString("marketingGroupUsed");
						member.packsOwnProduce = rs.getString("packsOwnProduce");
						member.marketGroup = rs.getString("marketGroup");
						member.brand = rs.getString("brand");
						member.status = rs.getString("status");
						*/
						member = getMember(rs);
						break;
					}
					return member;
				}

			});
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return member;
	}

	public Map<String, MemberVo> getMemberMap() {
		Map<String, MemberVo> memberMap = new HashMap<String, MemberVo>();

		Connection con = null;
		PreparedStatement stm = null;
		try {
			String sql = "SELECT * FROM Member";
			con = this.getDs().getConnection();
			stm = con.prepareStatement(sql);
			ResultSet rs = stm.executeQuery();
			while (rs.next()) {
				MemberVo member = getMember(rs);
				memberMap.put(member.memberId + "", member);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			this.close(stm);
			this.close(con);
		}
		return memberMap;
	}

	public ContactVo getContact(ResultSet rs) throws SQLException {
		ContactVo contact = new ContactVo();
		contact.contactId = (Integer) rs.getObject("contactId");
		contact.memberId = (Integer) rs.getObject("memberId");
		contact.firstname = rs.getString("firstname");
		contact.surname = rs.getString("surname");
		contact.BHPhone = rs.getString("BHPhone");
		contact.AHPhone = rs.getString("AHPhone");
		contact.fax = rs.getString("fax");
		contact.identifier = rs.getString("identifier");
		contact.mobile = rs.getString("mobile");
		contact.email = rs.getString("email");
		contact.service = rs.getString("service");
		contact.businessStreet = rs.getString("businessStreet");
		contact.businessCity = rs.getString("businessCity");
		contact.businessState = rs.getString("businessState");
		contact.businessCountry = rs.getString("businessCountry");
		contact.businessPostCode = rs.getString("businessPostCode");
		contact.postalStreet = rs.getString("postalStreet");
		contact.postalCity = rs.getString("postalCity");
		contact.postalState = rs.getString("postalState");
		contact.postalCountry = rs.getString("postalCountry");
		contact.postalPostCode = rs.getString("postalPostCode");

		contact.mailMemberId = (Integer) rs.getObject("mailMemberId");
		contact.mailContactId = (Integer) rs.getObject("mailContactId");
		contact.emailFaxContactId = (Integer) rs.getObject("emailFaxContactId");
		contact.status = rs.getString("status");

		return contact;
	}

	public ContactVo getContact(String contactId) {
		if (this.isEmpty(contactId)) return null;
		ContactVo contact = null;
		try {
			String sql = "SELECT * FROM Contact WHERE contactId=" + contactId;
			QueryRunner run = this.newQueryRunner();
			contact = run.query(sql, new ResultSetHandler<ContactVo>() {
				public ContactVo handle(ResultSet rs) throws SQLException {
					ContactVo contact = null;
					while (rs.next()) {
						contact = getContact(rs);
						break;
					}
					return contact;
				}

			});
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return contact;
	}

	public OrchardVo getOrchard(String orchardId) {
		if (this.isEmpty(orchardId)) return null;
		OrchardVo orchard = null;
		try {
			String sql = "SELECT * FROM Orchard WHERE orchardId=" + orchardId;
			QueryRunner run = this.newQueryRunner();
			orchard = run.query(sql, new ResultSetHandler<OrchardVo>() {
				public OrchardVo handle(ResultSet rs) throws SQLException {
					OrchardVo orchard = null;
					while (rs.next()) {
						orchard = getOrchard(rs);
						break;
					}
					return orchard;
				}

			});
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return orchard;
	}

	public List<ContactVo> getContactList(MemberVo member) {
		List<ContactVo> contactList = new ArrayList<ContactVo>();
		try {
			String sql = "SELECT * FROM Contact WHERE memberId=" + member.memberId + " ORDER BY contactId DESC";
			QueryRunner run = this.newQueryRunner();
			contactList = run.query(sql, new ResultSetHandler<ArrayList<ContactVo>>() {

				public ArrayList<ContactVo> handle(ResultSet rs) throws SQLException {
					ArrayList<ContactVo> result = new ArrayList<ContactVo>();
					while (rs.next()) {
						/*
						ContactVo contact = new ContactVo();
						contact.contactId = (Integer) rs.getObject("contactId");
						contact.memberId = (Integer) rs.getObject("memberId");
						contact.firstname = rs.getString("firstname");
						contact.surname = rs.getString("surname");
						contact.BHPhone = rs.getString("BHPhone");
						contact.AHPhone = rs.getString("AHPhone");
						contact.fax = rs.getString("fax");
						contact.identifier = rs.getString("identifier");
						contact.mobile = rs.getString("mobile");
						contact.email = rs.getString("email");
						contact.service = rs.getString("service");
						contact.businessStreet = rs.getString("businessStreet");
						contact.businessCity = rs.getString("businessCity");
						contact.businessState = rs.getString("businessState");
						contact.businessCountry = rs.getString("businessCountry");
						contact.businessPostCode = rs.getString("businessPostCode");
						contact.postalStreet = rs.getString("postalStreet");
						contact.postalCity = rs.getString("postalCity");
						contact.postalState = rs.getString("postalState");
						contact.postalCountry = rs.getString("postalCountry");
						contact.postalPostCode = rs.getString("postalPostCode");

						contact.mailMemberId = (Integer) rs.getObject("mailMemberId");
						contact.mailContactId = (Integer) rs.getObject("mailContactId");
						contact.emailFaxContactId = (Integer) rs.getObject("emailFaxContactId");
						contact.status = rs.getString("status");
						*/
						ContactVo contact = getContact(rs);
						result.add(contact);
					}
					return result;
				}

			});
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return contactList;
	}

	public Map<String, ContactVo> getContactMap() {
		Map<String, ContactVo> contactMap = new HashMap<String, ContactVo>();

		Connection con = null;
		PreparedStatement stm = null;
		try {
			String sql = "SELECT * FROM Contact ORDER BY memberId DESC, contactId DESC";
			con = this.getDs().getConnection();
			stm = con.prepareStatement(sql);
			ResultSet rs = stm.executeQuery();
			while (rs.next()) {
				ContactVo contact = getContact(rs);
				contactMap.put(contact.contactId + "", contact);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			this.close(stm);
			this.close(con);
		}
		return contactMap;
	}

	public List<ContactVo> getContactList() {
		List<ContactVo> contactList = new ArrayList<ContactVo>();

		Connection con = null;
		PreparedStatement stm = null;
		try {
			String sql = "SELECT * FROM Contact ORDER BY memberId DESC, contactId DESC";
			con = this.getDs().getConnection();
			stm = con.prepareStatement(sql);
			ResultSet rs = stm.executeQuery();
			while (rs.next()) {
				ContactVo contact = getContact(rs);
				contactList.add(contact);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			this.close(stm);
			this.close(con);
		}
		return contactList;
	}

	public OrchardVo getOrchard(ResultSet rs) throws SQLException {
		OrchardVo orchard = new OrchardVo();
		orchard.orchardId = (Integer) rs.getObject("orchardId");
		orchard.memberId = (Integer) rs.getObject("memberId");
		orchard.physicalLocation = rs.getString("physicalLocation");
		orchard.postCode = rs.getString("postCode");
		orchard.state = rs.getString("state");
		orchard.emailContactId = rs.getString("emailContactId");
		orchard.status = rs.getString("status");
		return orchard;
	}

	public List<OrchardVo> getOrchardList(MemberVo member) {
		List<OrchardVo> orchardList = new ArrayList<OrchardVo>();
		try {
			String sql = "SELECT * FROM Orchard WHERE memberId=" + member.memberId + " ORDER BY orchardId DESC";
			QueryRunner run = this.newQueryRunner();
			orchardList = run.query(sql, new ResultSetHandler<ArrayList<OrchardVo>>() {

				public ArrayList<OrchardVo> handle(ResultSet rs) throws SQLException {
					ArrayList<OrchardVo> result = new ArrayList<OrchardVo>();
					while (rs.next()) {
						/*
						OrchardVo orchard = new OrchardVo();
						orchard.orchardId = (Integer) rs.getObject("orchardId");
						orchard.memberId = (Integer) rs.getObject("memberId");
						orchard.physicalLocation = rs.getString("physicalLocation");
						orchard.postCode = rs.getString("postCode");
						orchard.state = rs.getString("state");
						orchard.emailContactId = rs.getString("emailContactId");
						orchard.status = rs.getString("status");
						*/
						OrchardVo orchard = getOrchard(rs);

						orchard.treeList = getTreeList(orchard);

						result.add(orchard);
					}
					return result;
				}

			});
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return orchardList;
	}

	public Map<String, OrchardVo> getOrchardMap() {
		Map<String, OrchardVo> orchardMap = new HashMap<String, OrchardVo>();

		Connection con = null;
		PreparedStatement stm = null;
		try {
			String sql = "SELECT * FROM Orchard ORDER BY memberId DESC, orchardId DESC";
			con = this.getDs().getConnection();
			stm = con.prepareStatement(sql);
			ResultSet rs = stm.executeQuery();
			while (rs.next()) {
				OrchardVo orchard = getOrchard(rs);
				orchardMap.put(orchard.orchardId + "", orchard);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			this.close(stm);
			this.close(con);
		}
		return orchardMap;
	}

	public Map<String, List<OrchardVo>> getOrchardListMap() {
		Map<String, List<OrchardVo>> orchardListMap = new HashMap<String, List<OrchardVo>>();

		Connection con = null;
		PreparedStatement stm = null;
		try {
			String sql = "SELECT * FROM Orchard ORDER BY memberId DESC, orchardId DESC";
			con = this.getDs().getConnection();
			stm = con.prepareStatement(sql);
			ResultSet rs = stm.executeQuery();
			while (rs.next()) {
				OrchardVo orchard = getOrchard(rs);
				List<OrchardVo> orchardList = orchardListMap.get(orchard.memberId + "");
				if (orchardList == null) {
					orchardList = new ArrayList<OrchardVo>();
					orchardListMap.put(orchard.memberId + "", orchardList);
				}
				orchardList.add(orchard);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			this.close(stm);
			this.close(con);
		}
		return orchardListMap;
	}

	public List<TreeVo> getTreeList(OrchardVo orchard) {
		List<TreeVo> treeList = new ArrayList<TreeVo>();
		try {
			String sql = "SELECT * FROM Tree WHERE orchardId=" + orchard.orchardId + " ORDER BY treeId DESC";
			QueryRunner run = this.newQueryRunner();
			treeList = run.query(sql, new ResultSetHandler<ArrayList<TreeVo>>() {

				public ArrayList<TreeVo> handle(ResultSet rs) throws SQLException {
					ArrayList<TreeVo> result = new ArrayList<TreeVo>();
					while (rs.next()) {
						TreeVo tree = new TreeVo();
						tree.treeId = (Integer) rs.getObject("treeId");
						tree.orchardId = (Integer) rs.getObject("orchardId");
						tree.yearPlanting = rs.getString("yearPlanting");
						tree.varietyId = (Integer) rs.getObject("varietyId");
						tree.DTR = rs.getString("DTR");
						tree.BTR = rs.getString("BTR");
						tree.area = rs.getString("area");
						tree.areaType = rs.getString("areaType");
						tree.tree = (Integer) rs.getObject("tree");

						result.add(tree);
					}
					return result;
				}

			});
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return treeList;
	}

	public List<VarietyVo> getVarietyList() {
		List<VarietyVo> result = null;
		try {
			String sql = "SELECT * FROM Variety ORDER BY varietyName";
			QueryRunner run = this.newQueryRunner();
			result = run.query(sql, new ResultSetHandler<List<VarietyVo>>() {
				public List<VarietyVo> handle(ResultSet rs) throws SQLException {
					List<VarietyVo> result = new ArrayList<VarietyVo>();
					while (rs.next()) {
						VarietyVo variety = new VarietyVo();
						variety.varietyId = (Integer) rs.getObject("varietyId");
						variety.varietyName = rs.getString("varietyName");
						result.add(variety);
					}
					return result;
				}

			});
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return result;
	}

	public List<RegionVo> getRegionList() {
		List<RegionVo> result = null;
		try {
			String sql = "SELECT * FROM Region ORDER BY regionName";
			QueryRunner run = this.newQueryRunner();
			result = run.query(sql, new ResultSetHandler<List<RegionVo>>() {
				public List<RegionVo> handle(ResultSet rs) throws SQLException {
					List<RegionVo> result = new ArrayList<RegionVo>();
					while (rs.next()) {
						RegionVo region = new RegionVo();
						region.regionId = (Integer) rs.getObject("regionId");
						region.regionName = rs.getString("regionName");
						region.postCodes = rs.getString("postCodes");
						region.subRegions = rs.getString("subRegions");
						region.state = rs.getString("state");
						result.add(region);
					}
					return result;
				}

			});
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return result;
	}

	public FlowerVo getFlower(ResultSet rs) throws SQLException {
		FlowerVo flower = new FlowerVo();
		flower.flowerId = (Long) rs.getObject("flowerId");
		flower.flowerYear = (Integer) rs.getObject("flowerYear");
		flower.memberId = (Integer) rs.getObject("memberId");
		flower.contact = (String) rs.getObject("contact");
		flower.block = (String) rs.getObject("block");
		flower.regionId = (Integer) rs.getObject("regionId");
		flower.subRegion = (String) rs.getObject("subRegion");
		flower.varietyId = (Integer) rs.getObject("varietyId");
		flower.tree = (Integer) rs.getObject("tree");

		flower.dateList = (String) rs.getObject("dateList");
		flower.percentList = (String) rs.getObject("percentList");
		return flower;
	}

	public LookupTVo getLookupT(ResultSet rs) throws SQLException {
		LookupTVo lookupT = new LookupTVo();
		lookupT.regionId = (Integer) rs.getObject("regionId");
		lookupT.varietyId = (Integer) rs.getObject("varietyId");
		lookupT.heat = (Integer) rs.getObject("heat");

		return lookupT;
	}

	public TemperatureVo getTempature(ResultSet rs) throws SQLException {
		TemperatureVo tempature = new TemperatureVo();
		tempature.regionId = (Integer) rs.getObject("regionId");
		tempature.dateT = rs.getDate("dateT");
		tempature.maxT = (Double) rs.getObject("maxT");
		tempature.minT = (Double) rs.getObject("minT");

		return tempature;
	}

	public List<FlowerVo> getFlowerList() {
		List<FlowerVo> flowerList = new ArrayList<FlowerVo>();
		Connection con = null;
		PreparedStatement stm = null;
		try {
			//Integer flowerYear = (Integer) this.perThreadRequest.get().getSession().getAttribute("flowerYear");
			Integer flowerYear = this.getFlowerYear();
			String sql = "SELECT * FROM Flower WHERE flowerYear=" + flowerYear + " ORDER BY flowerId ASC";
			con = this.getDs().getConnection();
			stm = con.prepareStatement(sql);
			ResultSet rs = stm.executeQuery();
			while (rs.next()) {
				FlowerVo flower = this.getFlower(rs);
				flowerList.add(flower);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			this.close(stm);
			this.close(con);
		}
		return flowerList;
	}

	public List<FlowerVo> getFlowerListByRegionIdList(List<String> regionIdList) {
		List<FlowerVo> flowerList = new ArrayList<FlowerVo>();
		Connection con = null;
		PreparedStatement stm = null;
		try {
			String regionWhere = "(";
			for (int i = 0; i < regionIdList.size(); i++) {
				String regionId = regionIdList.get(i);
				regionWhere += "regionId=" + regionId;
				if (i != regionIdList.size() - 1) regionWhere += " OR ";
			}
			regionWhere += ")";
			//Integer flowerYear = (Integer) this.perThreadRequest.get().getSession().getAttribute("flowerYear");
			Integer flowerYear = this.getFlowerYear();
			String sql = "SELECT * FROM Flower WHERE " + regionWhere + " AND flowerYear=" + flowerYear + " ORDER BY flowerId ASC";
			con = this.getDs().getConnection();
			stm = con.prepareStatement(sql);
			ResultSet rs = stm.executeQuery();
			while (rs.next()) {
				FlowerVo flower = this.getFlower(rs);
				flowerList.add(flower);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			this.close(stm);
			this.close(con);
		}
		return flowerList;
	}

	public List<FlowerVo> getFlowerListByRegionId(String regionId) {
		List<FlowerVo> flowerList = new ArrayList<FlowerVo>();
		Connection con = null;
		PreparedStatement stm = null;
		try {
			//Integer flowerYear = (Integer) this.perThreadRequest.get().getSession().getAttribute("flowerYear");
			Integer flowerYear = this.getFlowerYear();
			String sql = "SELECT * FROM Flower WHERE regionId=" + regionId + " AND flowerYear=" + flowerYear + " ORDER BY flowerId ASC";
			con = this.getDs().getConnection();
			stm = con.prepareStatement(sql);
			ResultSet rs = stm.executeQuery();
			while (rs.next()) {
				FlowerVo flower = this.getFlower(rs);
				flowerList.add(flower);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			this.close(stm);
			this.close(con);
		}
		return flowerList;
	}

	public List<LookupTVo> getLookupTListByKeyList(List<String> keyList) {
		List<LookupTVo> lookupTVoList = new ArrayList<LookupTVo>();
		Connection con = null;
		PreparedStatement stm = null;
		try {
			String where = "(";
			for (int i = 0; i < keyList.size(); i++) {
				String key = keyList.get(i);
				String[] arr = key.split("&&");
				String regionId = arr[0];
				String varietyId = arr[1];
				where += "( (regionId=0 OR regionId=" + regionId + ") AND varietyId=" + varietyId + ")";
				if (i != keyList.size() - 1) where += " OR ";
			}
			where += ")";

			String sql = "SELECT * FROM LookupT " + where + " ORDER BY regionId, varietyId ASC";
			con = this.getDs().getConnection();
			stm = con.prepareStatement(sql);
			ResultSet rs = stm.executeQuery();
			while (rs.next()) {
				LookupTVo lookupT = this.getLookupT(rs);
				lookupTVoList.add(lookupT);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			this.close(stm);
			this.close(con);
		}
		return lookupTVoList;
	}

	public List<LookupTVo> getLookupTList() {
		List<LookupTVo> lookupTVoList = new ArrayList<LookupTVo>();
		Connection con = null;
		PreparedStatement stm = null;
		try {
			String sql = "SELECT * FROM LookupT ORDER BY regionId, varietyId ASC";
			con = this.getDs().getConnection();
			stm = con.prepareStatement(sql);
			ResultSet rs = stm.executeQuery();
			while (rs.next()) {
				LookupTVo lookupT = this.getLookupT(rs);
				lookupTVoList.add(lookupT);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			this.close(stm);
			this.close(con);
		}
		return lookupTVoList;
	}

	public Object readObject(String path) {
		Object obj = null;
		FileInputStream f_in = null;
		ObjectInputStream obj_in = null;
		try {
			f_in = new FileInputStream(this.getFilePath(path));
			obj_in = new ObjectInputStream(f_in);
			obj = obj_in.readObject();
		} catch (Exception ex) {
			ex.printStackTrace();
			obj = null;
		} finally {
			if (obj_in != null) try {
				obj_in.close();
			} catch (IOException e) {
			}
			if (f_in != null) try {
				f_in.close();
			} catch (IOException e) {
			}
		}
		return obj;
	}

	public void writeObject(String path, Object obj) {
		FileOutputStream f_out = null;
		ObjectOutputStream obj_out = null;
		try {
			f_out = new FileOutputStream(this.getFilePath(path));
			obj_out = new ObjectOutputStream(f_out);
			obj_out.writeObject(obj);
		} catch (Exception ex) {
			obj = null;
		} finally {
			if (obj_out != null) try {
				obj_out.close();
			} catch (IOException e) {
			}
			if (f_out != null) try {
				f_out.close();
			} catch (IOException e) {
			}
		}
	}

	public Map<String, TemperatureUrlVo> getTemperatureUrlVoMap() {
		Map<String, TemperatureUrlVo> temperatureUrlVoMap = null;
		temperatureUrlVoMap = (Map<String, TemperatureUrlVo>) this.readObject("WEB-INF/temperatureUrlVoMap.data");
		if (temperatureUrlVoMap == null) temperatureUrlVoMap = new HashMap<String, TemperatureUrlVo>();
		return temperatureUrlVoMap;
	}

	public void saveTemperatureUrlVoMap(TemperatureUrlVo temperatureUrlVo) {
		Map<String, TemperatureUrlVo> temperatureUrlVoMap = this.getTemperatureUrlVoMap();
		temperatureUrlVoMap.put(temperatureUrlVo.regionId + "", temperatureUrlVo);
		this.writeObject("WEB-INF/temperatureUrlVoMap.data", temperatureUrlVoMap);
	}

	public List<EmailContentVo> viewEmailContentVoList() {
		List<EmailContentVo> emailContentList = (List<EmailContentVo>) this.readObject("WEB-INF/emailContentVoList.data");
		if (emailContentList == null) emailContentList = new ArrayList<EmailContentVo>();
		return emailContentList;
	}

	public List<SmsContentVo> viewSmsContentVoList() {
		List<SmsContentVo> smsContentList = (List<SmsContentVo>) this.readObject("WEB-INF/smsContentVoList.data");
		if (smsContentList == null) smsContentList = new ArrayList<SmsContentVo>();
		return smsContentList;
	}

	public List<EmailContentVo> viewEmailContentVoListSave(List<EmailContentVo> emailContentList) {
		this.writeObject("WEB-INF/emailContentVoList.data", emailContentList);
		return emailContentList;
	}

	public List<SmsContentVo> viewSmsContentVoListSave(List<SmsContentVo> smsContentList) {
		this.writeObject("WEB-INF/smsContentVoList.data", smsContentList);
		return smsContentList;
	}

	public List<TemperatureVo> getTempatureListByRegionId(String regionId) {
		List<TemperatureVo> tempatureVoList = new ArrayList<TemperatureVo>();
		Connection con = null;
		PreparedStatement stm = null;
		try {
			String sql = "SELECT * FROM Tempature WHERE regionId = " + regionId + " ORDER BY dateT ASC";
			con = this.getDs().getConnection();
			stm = con.prepareStatement(sql);
			ResultSet rs = stm.executeQuery();
			while (rs.next()) {
				TemperatureVo tempatureVo = this.getTempature(rs);
				tempatureVoList.add(tempatureVo);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			this.close(stm);
			this.close(con);
		}
		return tempatureVoList;
	}

	public List<TemperatureVo> getTempatureListByRegionIdList(List<String> regionIdList) {
		List<TemperatureVo> tempatureVoList = new ArrayList<TemperatureVo>();
		Connection con = null;
		PreparedStatement stm = null;
		try {
			String regionWhere = "(1=0";
			for (int i = 0; i < regionIdList.size(); i++) {
				String regionId = regionIdList.get(i);
				regionWhere += " OR ";
				regionWhere += "regionId=" + regionId;
			}
			regionWhere += ")";
			Integer flowerYear = this.getFlowerYear();

			String sql = "SELECT * FROM Tempature WHERE " + regionWhere + " AND YEAR(dateT) >= " + flowerYear + " ORDER BY dateT ASC";
			con = this.getDs().getConnection();
			stm = con.prepareStatement(sql);
			ResultSet rs = stm.executeQuery();
			while (rs.next()) {
				TemperatureVo tempatureVo = this.getTempature(rs);
				tempatureVoList.add(tempatureVo);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			this.close(stm);
			this.close(con);
		}
		return tempatureVoList;
	}

	public List<TemperatureVo> getTempature2ListByRegionIdList(List<String> regionIdList) {
		List<TemperatureVo> tempatureVoList = new ArrayList<TemperatureVo>();
		Connection con = null;
		PreparedStatement stm = null;
		try {
			String regionWhere = "(1=0";
			for (int i = 0; i < regionIdList.size(); i++) {
				String regionId = regionIdList.get(i);
				regionWhere += " OR ";
				regionWhere += "regionId=" + regionId;
			}
			regionWhere += ")";

			String sql = "SELECT * FROM Tempature2 WHERE " + regionWhere + " ORDER BY dateT ASC";
			con = this.getDs().getConnection();
			stm = con.prepareStatement(sql);
			ResultSet rs = stm.executeQuery();
			while (rs.next()) {
				TemperatureVo tempatureVo = this.getTempature(rs);
				tempatureVoList.add(tempatureVo);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			this.close(stm);
			this.close(con);
		}
		return tempatureVoList;
	}

	public void saveMember(MemberVo member) {
		Connection con = null;
		PreparedStatement stm = null;
		try {
			String sql = "REPLACE INTO Member SET memberId=? , businessName=?, abn=?, businessType=?, other=?, membershipType=?, financialMember=?, annualReport=?, authorisedContact=?, marketingGroupUsed=?, packsOwnProduce=?, marketGroup=?, brand=?, status=?";
			con = this.getDs().getConnection();
			stm = con.prepareStatement(sql);
			stm.setObject(1, member.memberId);
			stm.setString(2, member.businessName);
			stm.setString(3, member.abn);
			stm.setString(4, member.businessType);
			stm.setString(5, member.other);
			stm.setString(6, member.membershipType);
			stm.setString(7, member.financialMember);
			stm.setString(8, member.annualReport);
			stm.setObject(9, member.authorisedContact);
			stm.setString(10, member.marketingGroupUsed);
			stm.setString(11, member.packsOwnProduce);
			stm.setString(12, member.marketGroup);
			stm.setString(13, member.brand);
			stm.setString(14, member.status);
			stm.executeUpdate();

			for (int i = 0; i < member.contactList.size(); i++) {
				this.saveContact(member.contactList.get(i));
			}
			for (int i = 0; i < member.orchardList.size(); i++) {
				OrchardVo orchard = member.orchardList.get(i);
				this.saveOrchard(orchard);
				for (int j = 0; j < orchard.treeList.size(); j++) {
					this.saveTree(orchard.treeList.get(j));
				}
			}

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			this.close(stm);
			this.close(con);
		}
	}

	public void saveContact(ContactVo contact) {
		Connection con = null;
		PreparedStatement stm = null;
		try {
			String sql = "REPLACE INTO Contact SET contactId=?, memberId=?, firstname=?, surname=?, BHPhone=?, AHPhone=?, fax=?, identifier=?, mobile=?, email=?, service=?, businessStreet=?, businessCity=?, businessState=?, businessCountry=?, businessPostCode=?, postalStreet=?, postalCity=?, postalState=?, postalCountry=?, postalPostCode=?, mailMemberId=?, mailContactId=?, emailFaxContactId=?, status=?";
			con = this.getDs().getConnection();
			stm = con.prepareStatement(sql);
			stm.setObject(1, contact.contactId);
			stm.setObject(2, contact.memberId);
			stm.setString(3, contact.firstname);
			stm.setString(4, contact.surname);
			stm.setString(5, contact.BHPhone);
			stm.setString(6, contact.AHPhone);
			stm.setString(7, contact.fax);
			stm.setString(8, contact.identifier);
			stm.setString(9, contact.mobile);
			stm.setString(10, contact.email);
			stm.setString(11, contact.service);
			stm.setString(12, contact.businessStreet);
			stm.setString(13, contact.businessCity);
			stm.setString(14, contact.businessState);
			stm.setString(15, contact.businessCountry);
			stm.setString(16, contact.businessPostCode);
			stm.setString(17, contact.postalStreet);
			stm.setString(18, contact.postalCity);
			stm.setString(19, contact.postalState);
			stm.setString(20, contact.postalCountry);
			stm.setString(21, contact.postalPostCode);
			stm.setObject(22, contact.mailMemberId);
			stm.setObject(23, contact.mailContactId);
			stm.setObject(24, contact.emailFaxContactId);
			stm.setObject(25, contact.status);

			stm.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			this.close(stm);
			this.close(con);
		}
	}

	public void saveOrchard(OrchardVo orchard) {
		Connection con = null;
		PreparedStatement stm = null;
		try {
			String sql = "REPLACE INTO Orchard SET orchardId=?, memberId=?, physicalLocation=?, postCode=?, state=?, emailContactId=?, status=?";
			con = this.getDs().getConnection();
			stm = con.prepareStatement(sql);
			stm.setObject(1, orchard.orchardId);
			stm.setObject(2, orchard.memberId);
			stm.setString(3, orchard.physicalLocation);
			stm.setString(4, orchard.postCode);
			stm.setString(5, orchard.state);
			stm.setString(6, orchard.emailContactId);
			stm.setString(7, orchard.status);
			stm.executeUpdate();

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			this.close(stm);
			this.close(con);
		}
	}

	public void saveTree(TreeVo tree) {
		Connection con = null;
		PreparedStatement stm = null;
		try {
			String sql = "REPLACE INTO Tree SET treeId=?, orchardId=?, yearPlanting=?, varietyId=?, DTR=?, BTR=?, area=?, areaType=?, tree=?";
			con = this.getDs().getConnection();
			stm = con.prepareStatement(sql);
			stm.setObject(1, tree.treeId);
			stm.setObject(2, tree.orchardId);
			stm.setString(3, tree.yearPlanting);
			stm.setObject(4, tree.varietyId);
			stm.setString(5, tree.DTR);
			stm.setString(6, tree.BTR);
			stm.setString(7, tree.area);
			stm.setString(8, tree.areaType);
			stm.setObject(9, tree.tree);
			stm.executeUpdate();

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			this.close(stm);
			this.close(con);
		}
	}

	public void saveVariety(VarietyVo varietyVo) {
		Connection con = null;
		PreparedStatement stm = null;
		try {
			String sql = "REPLACE INTO Variety SET varietyId=?, varietyName=?";
			con = this.getDs().getConnection();
			stm = con.prepareStatement(sql);
			stm.setObject(1, varietyVo.varietyId);
			stm.setObject(2, varietyVo.varietyName);
			stm.executeUpdate();

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			this.close(stm);
			this.close(con);
		}
	}

	public void saveRegion(RegionVo regionVo) {
		Connection con = null;
		PreparedStatement stm = null;
		try {
			String sql = "REPLACE INTO Region SET regionId=?, regionName=?, postCodes=?, subRegions=?, state=?";
			con = this.getDs().getConnection();
			stm = con.prepareStatement(sql);
			stm.setObject(1, regionVo.regionId);
			stm.setObject(2, regionVo.regionName);
			stm.setObject(3, regionVo.postCodes);
			stm.setObject(4, regionVo.subRegions);
			stm.setObject(5, regionVo.state);
			stm.executeUpdate();

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			this.close(stm);
			this.close(con);
		}
	}

	public void saveTemperature(TemperatureVo temperatureVo) {
		Connection con = null;
		PreparedStatement stm = null;
		try {
			String sql = "REPLACE INTO Tempature SET regionId=?, dateT=?, maxT=?, minT=?";
			con = this.getDs().getConnection();
			stm = con.prepareStatement(sql);
			stm.setObject(1, temperatureVo.regionId);
			stm.setObject(2, temperatureVo.dateT);
			stm.setObject(3, temperatureVo.maxT);
			stm.setObject(4, temperatureVo.minT);
			stm.executeUpdate();

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			this.close(stm);
			this.close(con);
		}
	}

	public void saveFlower(FlowerVo flower) {
		Connection con = null;
		PreparedStatement stm = null;
		try {
			String sql = "REPLACE INTO Flower SET flowerYear=?, memberId=?, contact=?, block=?, regionId=?, subRegion=?, varietyId=?, tree=?, dateList=?, percentList=?";
			con = this.getDs().getConnection();
			stm = con.prepareStatement(sql);
			stm.setObject(1, flower.flowerYear);
			stm.setObject(2, flower.memberId);
			stm.setObject(3, flower.contact);
			stm.setObject(4, flower.block);
			stm.setObject(5, flower.regionId);
			stm.setObject(6, flower.subRegion);
			stm.setObject(7, flower.varietyId);
			stm.setObject(8, flower.tree);
			stm.setObject(9, flower.dateList);
			stm.setObject(10, flower.percentList);
			stm.executeUpdate();

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			this.close(stm);
			this.close(con);
		}
	}

	public void saveLookupT(LookupTVo lookupT) {
		Connection con = null;
		PreparedStatement stm = null;
		try {
			String sql = "REPLACE INTO LookupT SET regionId=?, varietyId=?, heat=?";
			con = this.getDs().getConnection();
			stm = con.prepareStatement(sql);
			stm.setObject(1, lookupT.regionId);
			stm.setObject(2, lookupT.varietyId);
			stm.setObject(3, lookupT.heat);
			stm.executeUpdate();

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			this.close(stm);
			this.close(con);
		}
	}

	public void removeFlowerAll(String memberId) {
		Connection con = null;
		PreparedStatement stm = null;
		try {
			con = this.getDs().getConnection();

			//Integer flowerYear = (Integer) this.perThreadRequest.get().getSession().getAttribute("flowerYear");
			Integer flowerYear = this.getFlowerYear();
			String sql = "DELETE FROM Flower WHERE memberId=" + memberId + " AND flowerYear=" + flowerYear;
			stm = con.prepareStatement(sql);
			stm.executeUpdate();
			stm.close();

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			this.close(stm);
			this.close(con);
		}
	}

	public void removeLookupTAll() {
		Connection con = null;
		PreparedStatement stm = null;
		try {
			con = this.getDs().getConnection();

			String sql = "DELETE FROM LookupT";
			stm = con.prepareStatement(sql);
			stm.executeUpdate();
			stm.close();

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			this.close(stm);
			this.close(con);
		}
	}

	public void removeMember(String memberId) {
		Connection con = null;
		PreparedStatement stm = null;
		try {
			String sql = "DELETE FROM Member WHERE memberId=" + memberId;
			con = this.getDs().getConnection();
			stm = con.prepareStatement(sql);
			stm.executeUpdate();

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			this.close(stm);
			this.close(con);
		}
	}

	public void removeContactAll(String memberId) {
		Connection con = null;
		PreparedStatement stm = null;
		try {
			String sql = "DELETE FROM Contact WHERE memberId=" + memberId;
			con = this.getDs().getConnection();
			stm = con.prepareStatement(sql);
			stm.executeUpdate();
			this.close(stm);

			sql = "UPDATE Orchard SET emailContactId='' WHERE memberId=" + memberId;
			stm = con.prepareStatement(sql);
			stm.executeUpdate();
			this.close(stm);

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			this.close(stm);
			this.close(con);
		}
	}

	public void removeOrchardAll(String memberId) {
		Connection con = null;
		PreparedStatement stm = null;
		try {
			String sql = "DELETE FROM Tree WHERE Tree.orchardId IN (SELECT Orchard.orchardId FROM Orchard WHERE Orchard.memberId=" + memberId + ")";
			con = this.getDs().getConnection();
			stm = con.prepareStatement(sql);
			stm.executeUpdate();
			this.close(stm);

			sql = "DELETE FROM Orchard WHERE memberId=" + memberId;
			stm = con.prepareStatement(sql);
			stm.executeUpdate();
			this.close(stm);
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			this.close(stm);
			this.close(con);
		}
	}

	public void removeContact(String contactId) {
		Connection con = null;
		PreparedStatement stm = null;
		try {
			String sql = "DELETE FROM Contact WHERE contactId=" + contactId;
			con = this.getDs().getConnection();
			stm = con.prepareStatement(sql);
			stm.executeUpdate();
			this.close(stm);

			sql = "UPDATE Orchard SET emailContactId=REPLACE(emailContactId,'&" + contactId + "&','') WHERE emailContactId like '%&" + contactId + "&%'";
			stm = con.prepareStatement(sql);
			stm.executeUpdate();
			this.close(stm);

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			this.close(stm);
			this.close(con);
		}
	}

	public void removeOrchard(String orchardId) {
		Connection con = null;
		PreparedStatement stm = null;
		try {
			String sql = "DELETE FROM Tree WHERE Tree.orchardId IN (SELECT Orchard.orchardId FROM Orchard WHERE Orchard.orchardId=" + orchardId + ")";
			con = this.getDs().getConnection();
			stm = con.prepareStatement(sql);
			stm.executeUpdate();
			this.close(stm);

			sql = "DELETE FROM Orchard WHERE orchardId=" + orchardId;
			stm = con.prepareStatement(sql);
			stm.executeUpdate();
			this.close(stm);
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			this.close(stm);
			this.close(con);
		}
	}

	public void removeTree(Integer treeId) {
		Connection con = null;
		PreparedStatement stm = null;
		try {
			String sql = "DELETE FROM Tree WHERE treeId=" + treeId;
			con = this.getDs().getConnection();
			stm = con.prepareStatement(sql);
			stm.executeUpdate();
			this.close(stm);

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			this.close(stm);
			this.close(con);
		}
	}

	public void removeVariety(Integer varietyId) {
		Connection con = null;
		PreparedStatement stm = null;
		try {
			String sql = "DELETE FROM Variety WHERE varietyId=" + varietyId;
			con = this.getDs().getConnection();
			stm = con.prepareStatement(sql);
			stm.executeUpdate();
			this.close(stm);

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			this.close(stm);
			this.close(con);
		}
	}

	public void removeRegion(Integer regionId) {
		Connection con = null;
		PreparedStatement stm = null;
		try {
			String sql = "DELETE FROM Region WHERE regionId=" + regionId;
			con = this.getDs().getConnection();
			stm = con.prepareStatement(sql);
			stm.executeUpdate();
			this.close(stm);

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			this.close(stm);
			this.close(con);
		}
	}

	public C view() {
		C c = new C();
		c.date = this.getDate();
		//c.date = new Date();
		//this.perThreadRequest.get().getSession().setAttribute("date", c.date);
		c.flowerYear = this.getFlowerYear();
		//this.perThreadRequest.get().getSession().setAttribute("flowerYear", c.flowerYear);
		//////
		AdminSearchVo adminSearchVo = new AdminSearchVo();
		//adminSearchVo.memberId = "3992";
		c.memberVo = this.viewMemberSearch(adminSearchVo);
		//////
		//c.memberVo = this.viewMemberSearch(new AdminSearchVo());
		c.varietyList = this.getVarietyList();
		c.regionList = this.getRegionList();
		c.memberPropertyVo = this.viewMemberPropertyVo();
		c.lookupTList = this.getLookupTList();
		c.temperatureUrlVoMap = this.getTemperatureUrlVoMap();
		c.emailContentList = this.viewEmailContentVoList();
		c.smsContentList = this.viewSmsContentVoList();
		//\\c.emailList = this.viewEmailVoList();
		return c;
	}

	public LoginVo login(String username, String password) {
		LoginVo login = new LoginVo();
		login.version = C._version;
		login.username = username;
		if ("admin".equals(username) && "pass@".equals(password)) {
			login.role = "admin";
		}
		return login;
	}

	public Date getDate() {
		Date date = (Date) this.perThreadRequest.get().getSession().getAttribute("date");
		if (date == null) {
			this.perThreadRequest.get().getSession().setAttribute("date", new Date());
			date = (Date) this.perThreadRequest.get().getSession().getAttribute("date");
		}
		return date;
	}

	public int getYear() {
		return 1900 + getDate().getYear();
	}

	public int getFlowerYear() {
		return 1900 + getDate().getYear();
	}

	public String viewMemberExport(List<String> memberIdList) {
		try {
			StringWriter outFile = new StringWriter();
			CsvListWriter csv = new CsvListWriter(outFile, CsvPreference.EXCEL_PREFERENCE);
			for (int i = 0; i < memberIdList.size(); i++) {
				String memberId = memberIdList.get(i);
				MemberVo member = this.getMember(memberId);
				List<ContactVo> contactList = this.getContactList(member);

				for (int j = 0; j < contactList.size(); j++) {
					ContactVo contact = contactList.get(j);

					List<String> list = new ArrayList<String>();
					list.add(member.businessName);
					list.add(contact.firstname);
					list.add(contact.surname);
					list.add(contact.postalStreet);
					list.add(contact.postalCity);
					list.add(contact.postalState);
					list.add(contact.postalPostCode);
					list.add(contact.postalCountry);

					csv.write(list);
				}
			}
			String str = outFile.toString();
			byte[] b = str.getBytes(Charset.forName("UTF-8"));
			int length = 0;

			HttpServletResponse resp = getThreadLocalResponse();
			ServletOutputStream op = resp.getOutputStream();
			ServletContext context = getServletConfig().getServletContext();
			resp.setContentType("application/octet-stream");
			resp.setContentLength((int) b.length);
			resp.setHeader("Content-Disposition", "attachment; filename*=\"utf-8''" + "MailingList.csv" + "");

			op.write(b);

			op.flush();
			op.close();

		} catch (Exception e) {
			// TODO: handle exception
		}

		return "Server says";
	}

	public MemberVo viewMember(String memberId) {
		MemberVo member = this.getMember(memberId);
		member.contactList = this.getContactList(member);
		member.orchardList = this.getOrchardList(member);
		member.flowerList = this.getFlowerList();
		return member;
	}

	public MemberVo viewMemberSearch(AdminSearchVo adminSearchVo) {
		List<String> memberIdList = this.getMemberIdList(adminSearchVo);
		List<String> contactIdList = adminSearchVo.contactIdList;
		//List<VarietyVo> varietyList = this.getVarietyList();
		MemberVo member = null;
		if (memberIdList == null) memberIdList = this.getMemberIdList(adminSearchVo);
		if (memberIdList == null) memberIdList = new ArrayList<String>();
		if (memberIdList.size() > 0) {
			String memberId = memberIdList.get(0);
			member = this.viewMember(memberId);
			member.memberIdList = memberIdList;
			member.contactIdList = contactIdList;
			//member.preAppended = adminSearchVo.appended;
			//member.varietyList = varietyList;
			//member.adminDbVo = this.viewAdminDb();
			member.current = 1;
		} else {
			member = new MemberVo();
			member.contactList = new ArrayList<ContactVo>();
			member.orchardList = new ArrayList<OrchardVo>();
			member.memberIdList = memberIdList;
			member.contactIdList = contactIdList;
			//member.preAppended = adminSearchVo.appended;
			//member.varietyList = varietyList;
			//member.adminDbVo = this.viewAdminDb();
			member.current = 0;
		}

		try {
			//			StringWriter outFile = new StringWriter();
			//			CsvListWriter csv = new CsvListWriter(outFile, CsvPreference.EXCEL_PREFERENCE);
			//			//CellProcessor[] Processing = new CellProcessor[] { null, new ConvertNullTo(-1), null, new ConvertNullTo("\"\"") };
			//
			//			String[] header = new String[] { "Business Name", "Firstname", "Surname", "Postal Street", "Postal City", "Postal State", "Postal PostCode", "Postal Country" };
			//			csv.writeHeader(header);
			//			String str = "";
			//List<ContactVo> contactList = new ArrayList<ContactVo>();

			C._mailCode = 0;
			//member.contactEmailList = new ArrayList<EmailVo>();
			member.searchContactList = new ArrayList<ContactVo>();
			Map<String, MemberVo> memberMap = this.getMemberMap();
			for (int i = 0; i < member.contactIdList.size(); i++) {
				String contactId = contactIdList.get(i);
				ContactVo contactVo = this.getContact(contactId);
				MemberVo memberVo = memberMap.get(contactVo.memberId + "");
				if (memberVo != null) contactVo.memberBusinessName = memberVo.businessName;
				/*
				EmailVo emailVo = new EmailVo();

				emailVo.memberId = contactVo.memberId + "";
				emailVo.contactId = contactVo.contactId + "";
				emailVo.orchardId = "";

				emailVo.memberHeader = contactVo.memberId + "";
				emailVo.contactHeader = contactVo.getCaption();
				emailVo.orchardHeader = "";

				//emailVo.email = contactVo.email;
				if (!"".equals(contactVo.email)) {
					if (mailCode % 3 == 0) emailVo.email = "idm@mangoes.net.au";//"no_reply@mangoes.net.au";//contactVo.email
					if (mailCode % 3 == 1) emailVo.email = "mangomail001@yahoo.com";
					if (mailCode % 3 == 2) emailVo.email = "idm@mangoes.net.au";
					mailCode++;

					//\\emailVo.email = contactVo.email;
				} else emailVo.email = "";
				emailVo.statusEmail = "";

				if (!"".equals(contactVo.fax)) emailVo.fax = "0738461966";//contactVo.fax;
				else emailVo.fax = "";
				emailVo.statusFax = "";

				if (!"".equals(contactVo.mobile)) emailVo.sms = "0400808689";//contactVo.mobile
				else emailVo.sms = "";
				emailVo.statusSms = "";
				*/
				//EmailVo emailVo = C.getEmailVo(contactVo);
				//member.contactEmailList.add(emailVo);
				member.searchContactList.add(contactVo);

				/////////
				//				List<String> list = new ArrayList<String>();
				//				MemberVo mem = this.getMember(contactVo.memberId + "");
				//				list.add(mem.businessName);
				//				//list.add(mem.memberId + "");
				//				list.add(contactVo.firstname);
				//				list.add(contactVo.surname);
				//				list.add(contactVo.postalStreet);
				//				list.add(contactVo.postalCity);
				//				list.add(contactVo.postalState);
				//				list.add(contactVo.postalPostCode);
				//				list.add(contactVo.postalCountry);
				//
				//				csv.write(list);
				//
				//				str += mem.memberId + "," + contactVo.firstname + "," + contactVo.surname + "," + contactVo.postalStreet + "," + contactVo.postalCity + "," + contactVo.postalState + "," + contactVo.postalPostCode + "," + contactVo.postalCountry + "\n";
				/////////
				//contactList.add(contactVo);
			}
			this.perThreadRequest.get().getSession().setAttribute("searchContactList", member.searchContactList);

		} catch (Exception e) {
			e.printStackTrace();
		}

		///////////////////////
		return member;
	}

	public MemberVo viewMemberSaveMail(MemberVo memberVo) {
		MemberVo member = this.viewMemberSave(memberVo);
		try {
			if ("YES".equals(memberVo.financialMember) && memberVo.authorisedContact != null) {
				final MemberPropertyVo memberPropertyVo = this.viewMemberPropertyVo();
				String host = memberPropertyVo.STMPserverSec;
				String from = memberPropertyVo.emailSec;
				Properties properties = System.getProperties();
				properties.setProperty("mail.smtp.host", host);
				properties.setProperty("mail.smtp.auth", "true");
				//properties.setProperty("mail.smtp.starttls.enable", "true");
				Session session = Session.getDefaultInstance(properties, new javax.mail.Authenticator() {
					protected PasswordAuthentication getPasswordAuthentication() {
						return new PasswordAuthentication(memberPropertyVo.accountSec, memberPropertyVo.passSec);
					}
				});

				String to = memberPropertyVo.emailSec;
				MimeMessage message = new MimeMessage(session);
				message.setFrom(new InternetAddress(from));
				message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
				message.setSubject("ADMIN: notification of changed");
				String content = "";
				ContactVo aContact = memberVo.getContact(memberVo.authorisedContact + "");
				content += "<b>Members/Business Name:</b> " + member.businessName + "<br/>";
				content += "<b>Authorised Contact:</b> " + aContact.getCaption() + "<br/>";
				content += "First name: " + aContact.firstname + "<br/>";
				content += "Surname: " + aContact.surname + "<br/>";
				content += "BH Phone: " + aContact.BHPhone + "<br/>";
				content += "AH Phone: " + aContact.AHPhone + "<br/>";
				content += "Fax: " + aContact.fax + "<br/>";
				content += "Identifier: " + aContact.identifier + "<br/>";
				content += "Mobile: " + aContact.mobile + "<br/>";
				content += "Email: " + aContact.email + "<br/>";
				content += "Service: " + aContact.getService() + "<br/>";
				content += "<b>Mail Sample:</b><br/>";
				content += member.getSampleMail(aContact, "<br/>");
				message.setContent(content, "text/html");
				Transport.send(message);
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return member;
	}

	public MemberVo viewMemberSave(MemberVo memberVo) {
		this.saveMember(memberVo);
		return this.viewMember(memberVo.memberId + "");
	}

	public MemberVo viewMemberAdd(MemberVo memberVo) {
		this.saveMember(memberVo);
		MemberVo member = new MemberVo();
		this.saveMember(member);
		return this.viewMemberSearch(new AdminSearchVo());
	}

	public MemberVo viewMemberRemove(MemberVo memberVo) {
		if ("".equals(memberVo.status)) {
			memberVo.status = "suspended";
			this.saveMember(memberVo);
			//return this.viewMemberSearch(new AdminSearchVo());
			return this.viewMember(memberVo.memberId + "");
		}

		this.removeOrchardAll(memberVo.memberId + "");
		this.removeContactAll(memberVo.memberId + "");
		this.removeMember(memberVo.memberId + "");
		return this.viewMemberSearch(new AdminSearchVo());
	}

	public MemberVo viewMemberActive(MemberVo memberVo) {
		memberVo.status = "";
		this.saveMember(memberVo);
		//return this.viewMemberSearch(new AdminSearchVo());
		return this.viewMember(memberVo.memberId + "");
	}

	public MemberVo viewContactAdd(MemberVo memberVo) {
		this.saveMember(memberVo);
		ContactVo contact = new ContactVo();
		contact.memberId = memberVo.memberId;
		this.saveContact(contact);
		return this.viewMember(memberVo.memberId + "");
	}

	public MemberVo viewContactRemove(MemberVo memberVo, String contactId) {
		ContactVo contactVo = memberVo.getContact(contactId);
		if ("".equals(contactVo.status)) {
			contactVo.status = "suspended";
			this.saveMember(memberVo);
			return this.viewMember(memberVo.memberId + "");
		}

		this.saveMember(memberVo);
		this.removeContact(contactId);
		return this.viewMember(memberVo.memberId + "");
	}

	public MemberVo viewContactActive(MemberVo memberVo, String contactId) {
		ContactVo contactVo = memberVo.getContact(contactId);
		contactVo.status = "";
		this.saveMember(memberVo);
		return this.viewMember(memberVo.memberId + "");
	}

	public MemberVo viewOrchardAdd(MemberVo memberVo) {
		this.saveMember(memberVo);
		OrchardVo orchard = new OrchardVo();
		orchard.memberId = memberVo.memberId;
		this.saveOrchard(orchard);
		return this.viewMember(memberVo.memberId + "");
	}

	public MemberVo viewOrchardRemove(MemberVo memberVo, String orchardId) {
		OrchardVo orchardVo = memberVo.getOrchard(orchardId);
		if ("".equals(orchardVo.status)) {
			orchardVo.status = "suspended";
			this.saveMember(memberVo);
			return this.viewMember(memberVo.memberId + "");
		}

		this.saveMember(memberVo);
		this.removeOrchard(orchardId);
		return this.viewMember(memberVo.memberId + "");
	}

	public MemberVo viewOrchardActive(MemberVo memberVo, String orchardId) {
		OrchardVo orchardVo = memberVo.getOrchard(orchardId);
		orchardVo.status = "";
		this.saveMember(memberVo);
		return this.viewMember(memberVo.memberId + "");
	}

	public MemberVo viewTreeAdd(MemberVo memberVo, Integer orchardId) {
		this.saveMember(memberVo);
		TreeVo tree = new TreeVo();
		tree.orchardId = orchardId;
		this.saveTree(tree);
		return this.viewMember(memberVo.memberId + "");
	}

	public MemberVo viewTreeRemove(MemberVo memberVo, Integer treeId) {
		this.saveMember(memberVo);
		this.removeTree(treeId);
		return this.viewMember(memberVo.memberId + "");
	}

	public List<VarietyVo> viewVariety() {
		return this.getVarietyList();
	}

	public List<VarietyVo> viewVarietySave(List<VarietyVo> varietyList) {
		for (int i = 0; i < varietyList.size(); i++) {
			VarietyVo _varietyVo = varietyList.get(i);
			this.saveVariety(_varietyVo);
		}
		return this.viewVariety();
	}

	public List<VarietyVo> viewVarietyAdd() {
		VarietyVo varietyVo = new VarietyVo();
		this.saveVariety(varietyVo);
		return this.viewVariety();
	}

	public List<VarietyVo> viewVarietyRemove(Integer varietyId) {
		this.removeVariety(varietyId);
		return this.viewVariety();
	}

	public List<RegionVo> viewRegion() {
		return this.getRegionList();
	}

	public List<RegionVo> viewRegionSave(List<RegionVo> regionList) {
		for (int i = 0; i < regionList.size(); i++) {
			RegionVo _regionVo = regionList.get(i);
			this.saveRegion(_regionVo);
		}
		return this.viewRegion();
	}

	public List<RegionVo> viewRegionAdd() {
		RegionVo regionVo = new RegionVo();
		this.saveRegion(regionVo);
		return this.viewRegion();
	}

	public List<RegionVo> viewRegionRemove(Integer regionId) {
		this.removeRegion(regionId);
		return this.viewRegion();
	}

	public List<FlowerVo> viewFlowerSave(String memberId, List<FlowerVo> flowerList) {
		this.removeFlowerAll(memberId);
		for (int i = 0; i < flowerList.size(); i++) {
			FlowerVo flower = flowerList.get(i);
			this.saveFlower(flower);
		}

		return this.getFlowerList();
	}

	public List<LookupTVo> viewLookupTSave(List<LookupTVo> lookupTList) {
		this.removeLookupTAll();
		for (int i = 0; i < lookupTList.size(); i++) {
			LookupTVo lookupTVo = lookupTList.get(i);
			this.saveLookupT(lookupTVo);
		}

		return this.getLookupTList();
	}

	public Date toHarvestDate(String regionId, int varietyId, Date flowerDate, List<LookupTVo> loolupTVoList, Map<String, List<TemperatureVo>> tempatureListMap) {
		Integer heat = 1590;
		for (int i = 0; i < loolupTVoList.size(); i++) {
			LookupTVo lookupT = loolupTVoList.get(i);
			if (lookupT.regionId == 0 || regionId.equals(lookupT.regionId + "")) {
				if (lookupT.varietyId == varietyId) heat = lookupT.heat;
			}
		}
		if (heat == null) return null;
		Double heatAcc = 0.0;
		List<TemperatureVo> tempatureList = tempatureListMap.get(regionId);
		for (int i = 0; i < tempatureList.size(); i++) {
			TemperatureVo tempature = tempatureList.get(i);
			if (tempature.dateT.before(flowerDate)) continue;
			Double heatUnit = (tempature.maxT + tempature.minT) / 2 - 12;
			if (heatUnit < 0) heatUnit = 0.0;
			heatAcc += heatUnit;
			if (heatAcc >= heat) {
				//
				return tempature.dateT;
			}
		}
		Date date = null;
		return date;
	}

	public Map<String, Date> getHarvestMap(List<String> keyList) {
		Map<String, String> regionMap = C.getRegionMap();
		Map<String, String> varietyMap = C.getVarietyMap();

		List<String> regionVarietyList = new ArrayList<String>();
		List<String> regionIdList = new ArrayList<String>();
		for (String key : keyList) {
			String arr[] = key.split("&&");
			String regionId = arr[0];
			String varietyId = arr[1];
			String regionVariety = regionId + "&&" + varietyId;
			if (!regionVarietyList.contains(regionVariety)) regionVarietyList.add(regionVariety);
			if (!regionIdList.contains(regionId)) regionIdList.add(regionId);
		}
		Map<String, Date> harvestMap = new HashMap<String, Date>();
		Map<String, LookupTVo> lookupTMap = this.getLookupTMap(regionVarietyList);
		/*
		Map<String, List<TempatureVo>> tempatureMap = new HashMap<String, List<TempatureVo>>();
		List<TempatureVo> tempatureFullList = this.getTempatureListByRegionIdList(regionIdList);
		for (int i = 0; i < tempatureFullList.size(); i++) {
			TempatureVo tempatureVo = tempatureFullList.get(i);
			String regionId = tempatureVo.regionId + "";
			List<TempatureVo> tempatureList = tempatureMap.get(regionId);
			if (tempatureList == null) {
				tempatureList = new ArrayList<TempatureVo>();
				tempatureMap.put(regionId, tempatureList);
			}
			tempatureList.add(tempatureVo);
			tempatureMap.put(regionId, tempatureList);
		}
		tempatureFullList = null;
		*/
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		Map<String, TemperatureVo> tempatureMap = new HashMap<String, TemperatureVo>();
		List<TemperatureVo> tempatureFullList = this.getTempatureListByRegionIdList(regionIdList);
		for (int i = 0; i < tempatureFullList.size(); i++) {
			TemperatureVo tempatureVo = tempatureFullList.get(i);
			String key = tempatureVo.regionId + "&&" + df.format(tempatureVo.dateT);
			tempatureMap.put(key, tempatureVo);
		}
		tempatureFullList = null;

		DateFormat df2 = new SimpleDateFormat("MM-dd");
		Map<String, TemperatureVo> tempature2Map = new HashMap<String, TemperatureVo>();
		List<TemperatureVo> tempature2FullList = this.getTempature2ListByRegionIdList(regionIdList);
		for (int i = 0; i < tempature2FullList.size(); i++) {
			TemperatureVo tempatureVo = tempature2FullList.get(i);
			String key = tempatureVo.regionId + "&&" + df2.format(tempatureVo.dateT);
			tempature2Map.put(key, tempatureVo);
		}
		tempature2FullList = null;

		DateFormat dateFormat = new SimpleDateFormat("dd-MMM-yyyy");
		DecimalFormat doubleF = new DecimalFormat("#.##");

		Map<String, Double> accMap = new HashMap<String, Double>();
		for (String regionIdK : regionIdList) {
			chartLog.append("<b><u>").append(regionMap.get(regionIdK)).append("</u></b>");
			chartLog.append("<table>");
			chartLog.append("<tr><td style='width:300'><b><u>dateT</u></b></td>");
			chartLog.append("<td style='width:80'><b><u>maxT</u></b></td>");
			chartLog.append("<td style='width:80'><b><u>minT</u></b></td>");
			chartLog.append("<td style='width:80'><b><u>heatUnit</u></b></td>");
			chartLog.append("<td style='width:80'><b><u>Current/Average</u></b></td></tr>");

			boolean display = true;
			Date date = new Date(this.getFlowerYear() - 1900, 1 - 1, 1);
			int count = 0;
			String CA = "current";
			while (1 == 1) {
				count++;
				if (count >= 2 * 365) break;
				TemperatureVo tempature = null;
				String keyT = regionIdK + "&&" + df.format(date);
				String keyT2 = regionIdK + "&&" + df2.format(date);
				df2.format(date);

				CA = "";
				tempature = tempatureMap.get(keyT);
				if (tempature == null) {
					tempature = tempature2Map.get(keyT2);
					if (tempature != null) {
						tempature.dateT = new java.sql.Date(date.getTime());
						CA = "average";
					}
				}

				if (tempature == null) {
					date = new Date(date.getTime() + 24 * 60 * 60 * 1000);
					continue;
				}

				Double heatUnit = (tempature.maxT + tempature.minT) / 2 - 12;

				int j = 0;
				display = false;
				StringBuffer buf0 = new StringBuffer();
				StringBuffer buf = new StringBuffer();
				for (String key : keyList) {
					String arr[] = key.split("&&");
					String regionId = arr[0];
					String varietyId = arr[1];
					Date flowerDate = null;
					try {
						flowerDate = dateFormat.parse(arr[2]);
					} catch (ParseException e) {
					}
					if (!regionId.equals(regionIdK)) continue;

					if (tempature.dateT.before(flowerDate)) {
						buf.append("<td>").append("&nbsp;").append("</td>");
						continue;
					}
					if (harvestMap.get(key) != null) {
						buf.append("<td>").append("&nbsp;").append("</td>");
						continue;
					}
					display = true;

					LookupTVo lookupTVo = lookupTMap.get(regionId + "&&" + varietyId);
					Integer heat = null;
					if (lookupTVo != null) heat = lookupTVo.heat;
					if (heat == null) continue;

					String str1 = "";
					Double acc = accMap.get(key);
					if (acc == null) {
						str1 = regionMap.get(regionId) + "_" + varietyMap.get(varietyId) + " " + dateFormat.format(tempature.dateT) + " : ";
						acc = 0.0;
					}

					if (heatUnit < 0) heatUnit = 0.0;
					acc += heatUnit;
					accMap.put(key, acc);
					if (acc >= heat) {
						str1 = regionMap.get(regionId) + "_" + varietyMap.get(varietyId) + " " + dateFormat.format(tempature.dateT) + " : ";
						harvestMap.put(key, tempature.dateT);
					}
					buf.append("<td>").append(str1 + Math.round(acc)).append("</td>");
					j++;
				}

				if (display) {
					buf0.append("<tr><td>").append(tempature.dateT).append("</td>");
					buf0.append("<td>").append(tempature.maxT).append("</td>");
					buf0.append("<td>").append(tempature.minT).append("</td>");
					buf0.append("<td>").append(doubleF.format(heatUnit)).append("</td>");
					buf0.append("<td>").append(CA).append("</td>");
				}

				if (display) buf.append("</tr>");
				chartLog.append(buf0).append(buf);
				/*
				boolean done = false;
				for (String key : keyList) {
					if (harvestMap.get(key) == null) continue;
					done = true;
				}
				if (done) break;
				*/
				date = new Date(date.getTime() + 24 * 60 * 60 * 1000);
			}
			chartLog.append("</table>");
		}

		chartLog.append("<table border=0 cellspacing=0>");
		chartLog.append("<tr><td style='width:80'><b><u>region</u></b></td>");
		chartLog.append("<td style='width:100'><b><u>variety</u></b></td>");
		chartLog.append("<td style='width:100'><b><u>startDate</u></b></td>");
		chartLog.append("<td style='width:100'><b><u>harvestDate</u></b></td>");
		chartLog.append("<td style='width:100'><b><u>modifiedDate</u></b></td></tr>");

		List<String> keyList2 = new ArrayList<String>(harvestMap.keySet());
		Collections.sort(keyList2);

		for (String key : keyList2) {
			String arr[] = key.split("&&");
			String regionId = arr[0];
			String varietyId = arr[1];
			Date flowerDate = null;
			try {
				flowerDate = dateFormat.parse(arr[2]);
			} catch (ParseException e) {
			}
			Date date = harvestMap.get(key);
			/*
			Calendar cal = Calendar.getInstance();
			cal.setTime(date);
			cal.set(Calendar.WEEK_OF_YEAR, cal.get(Calendar.WEEK_OF_YEAR));
			Date modDate = cal.getTime();
			*/
			Date modDate = date;
			for (int j = 0; j < 300; j++) {
				Date start = new Date(C._flowerYear - 1900, C._memberPropertyVo.startMonth - 1, C._memberPropertyVo.startDay);
				//CalendarUtil.addDaysToDate(start, j * C._memberPropertyVo.interval);
				CalendarUtil.addDaysToDate(start, j * 7);
				if (start.after(date)) {
					modDate = start;
					break;
				}
			}

			chartLog.append("<tr>");
			chartLog.append("<td>").append(regionMap.get(regionId)).append("</td>");
			chartLog.append("<td>").append(varietyMap.get(varietyId)).append("</td>");
			chartLog.append("<td>").append(arr[2]).append("</td>");
			chartLog.append("<td>").append(dateFormat.format(date)).append("</td>");
			chartLog.append("<td>").append(dateFormat.format(modDate)).append("</td>");
			chartLog.append("</tr>");
			harvestMap.put(key, modDate);
		}
		chartLog.append("</table>");
		return harvestMap;
	}

	public Map<String, LookupTVo> getLookupTMap(List<String> keyList) {
		Map<String, String> regionMap = C.getRegionMap();
		Map<String, String> varietyMap = C.getVarietyMap();

		chartLog.append("<table border=0 cellspacing=0>");
		chartLog.append("<tr><td style='width:80'><b><u>region</u></b></td>");
		chartLog.append("<td style='width:100'><b><u>variety</u></b></td>");
		chartLog.append("<td style='width:80'><b><u>default</u></b></td>");
		chartLog.append("<td style='width:80'><b><u>manual</u></b></td>");
		chartLog.append("<td style='width:80'><b><u>heat</u></b></td>");
		chartLog.append("</tr>");

		Map<String, LookupTVo> lookupTMap = new HashMap<String, LookupTVo>();
		Map<String, LookupTVo> _lookupTMap = new HashMap<String, LookupTVo>();
		for (LookupTVo lookupTVo : this.getLookupTList()) {
			String key = lookupTVo.regionId + "&&" + lookupTVo.varietyId;
			_lookupTMap.put(key, lookupTVo);
		}
		Map<String, String> keyMap = new HashMap<String, String>();
		for (String key : keyList) {
			String arr[] = key.split("&&");
			String regionId = arr[0];
			String varietyId = arr[1];

			chartLog.append("<tr><td>").append(regionMap.get(regionId)).append("</td>");
			chartLog.append("<td>").append(varietyMap.get(varietyId)).append("</td>");

			String defaultKey = "0&&" + varietyId;
			LookupTVo defaultVo = _lookupTMap.get(defaultKey);
			if (defaultVo != null) {
				lookupTMap.put(key, defaultVo);
				chartLog.append("<td>").append(defaultVo.heat).append("</td>");
			} else chartLog.append("<td>").append("&nbsp;").append("</td>");

			LookupTVo manualVo = _lookupTMap.get(key);
			if (manualVo != null) {
				lookupTMap.put(key, manualVo);
				chartLog.append("<td>").append(manualVo.heat).append("</td>");
			} else chartLog.append("<td>").append("&nbsp;").append("</td>");

			LookupTVo vo = lookupTMap.get(key);
			if (vo != null) {
				chartLog.append("<td>").append(vo.heat).append("</td>");
			} else chartLog.append("<td>").append("&nbsp;").append("</td>");

			chartLog.append("</tr>");
		}
		chartLog.append("</table>");
		return lookupTMap;
	}

	public StringBuffer chartLog;

	public Map<String, Map<String, FlowerChartVo>> viewFlowerChart(List<String> regionIdList) {
		chartLog = new StringBuffer();
		Log log = Log.get(this.getFilePath("Log.html"));
		C._regionVoList = this.getRegionList();
		C._varietyVoList = this.getVarietyList();
		C._memberPropertyVo = this.viewMemberPropertyVo();
		C._flowerYear = this.getFlowerYear();
		//List<String> startFlowerDateList = C.getStartFlowerDateList("dd-MMM");
		List<String> startFlowerDateList = new ArrayList<String>();
		DateFormat dtf = new SimpleDateFormat("dd-MMM");
		for (int j = 0; j < C._memberPropertyVo.columns; j++) {
			Date start = new Date(C._flowerYear - 1900, C._memberPropertyVo.startMonth - 1, C._memberPropertyVo.startDay);
			CalendarUtil.addDaysToDate(start, j * C._memberPropertyVo.interval);
			startFlowerDateList.add(dtf.format(start));
		}

		//List<String> endFlowerDateList = C.getEndFlowerDateList("dd-MMM");
		List<String> endFlowerDateList = new ArrayList<String>();
		//DateTimeFormat dtf = DateTimeFormat.getFormat(format);
		for (int j = 0; j < C._memberPropertyVo.columns; j++) {
			Date end = new Date(C._flowerYear - 1900, C._memberPropertyVo.startMonth - 1, C._memberPropertyVo.startDay);
			CalendarUtil.addDaysToDate(end, (j + 1) * C._memberPropertyVo.interval - 1);
			endFlowerDateList.add(dtf.format(end));
		}

		chartLog.append("<table border=0 cellspacing=0>");
		chartLog.append("<tr><td style='width:80'><b><u>contact</u></b></td>");
		chartLog.append("<td style='width:80'><b><u>region</u></b></td>");
		chartLog.append("<td style='width:100'><b><u>variety</u></b></td>");
		chartLog.append("<td style='width:20'>&nbsp;</td>");
		for (int i = 0; i < C._memberPropertyVo.columns; i++) {
			chartLog.append("<td style='width:60'><b>" + startFlowerDateList.get(i) + "</b></td>");
		}
		chartLog.append("</tr>");

		chartLog.append("<tr><td><b><u>block</u></b></td>");
		chartLog.append("<td><b><u>sub-region</u></b></td>");
		chartLog.append("<td><b><u>trees</u></b></td>");
		chartLog.append("<td style='width:20'>&nbsp;</td>");
		for (int i = 0; i < C._memberPropertyVo.columns; i++) {
			chartLog.append("<td><b>" + endFlowerDateList.get(i) + "</b></td>");
		}
		chartLog.append("</tr>");

		List<FlowerVo> flowerList = this.getFlowerListByRegionIdList(regionIdList);

		Map<String, String> regionMap = C.getRegionMap();
		Map<String, String> varietyMap = C.getVarietyMap();
		/*
		Map<String, String> regionSelectMap = new HashMap<String, String>();
		for (String regionId : regionIdList) {
			regionSelectMap.put(regionId, regionId);
		}
		*/
		HTML html;

		Map<String, FlowerVo> flowerMap = new HashMap<String, FlowerVo>();
		for (int i = 0; i < flowerList.size(); i++) {
			FlowerVo flower = flowerList.get(i);
			//if (regionSelectMap.get(flower.regionId + "") == null) continue;

			String key = flower.regionId + "&&" + flower.varietyId;
			FlowerVo _flower = flowerMap.get(key);
			if (_flower == null) {
				_flower = new FlowerVo();
				_flower.regionId = flower.regionId;
				_flower.varietyId = flower.varietyId;
				_flower.tree = 0;
				_flower._treeNumList = new ArrayList<Integer>();
				for (int j = 0; j < C._memberPropertyVo.columns; j++) {
					_flower._treeNumList.add(j, 0);
				}
				flowerMap.put(key, _flower);
			}

			_flower.tree += flower.tree;

			List<Integer> treeNumList = flower.getTreeNumList();
			for (int j = 0; j < C._memberPropertyVo.columns; j++) {
				if (j < treeNumList.size()) {
					Integer treeNum = treeNumList.get(j);
					if (treeNum == null) continue;
					_flower._treeNumList.set(j, treeNum + _flower._treeNumList.get(j));
				}
			}
		}
		List<String> keyListFull = new ArrayList<String>();

		List<String> keyList = new ArrayList<String>(flowerMap.keySet());
		Collections.sort(keyList);

		dtf = new SimpleDateFormat("dd-MMM-yyyy");
		int i = 0;
		for (String key : keyList) {
			FlowerVo flower = flowerMap.get(key);
			//public Integer flowerId;
			//flower.flowerYear = C._flowerYear;
			//flower.memberId = C._memberVo.memberId;

			//if (!C._memberVo.memberId.equals(flower.memberId)) continue;
			//if (regionSelectMap.get(flower.regionId + "") == null) continue;

			chartLog.append("<tr><td style='border-top: 2px solid BLUE;'>").append(flower.tdNull0(flower.contact)).append("</td>");
			chartLog.append("<td style='border-top: 2px solid BLUE;'>").append(flower.tdNull0(regionMap.get(flower.regionId + ""))).append("</td>");
			chartLog.append("<td style='border-top: 2px solid BLUE;'>").append(flower.tdNull0(varietyMap.get(flower.varietyId + ""))).append("</td>");
			chartLog.append("<td style='border-top: 2px solid BLUE;'><b>").append(i + 1).append("</b></td>");
			List<Integer> treeNumList = flower.getTreeNumList();
			for (int j = 0; j < C._memberPropertyVo.columns; j++) {
				if (j < treeNumList.size()) {
					//if (treeNumList.get(j) == 0) continue;
					chartLog.append("<td style='border-top: 2px solid BLUE;'>").append("<b style='color:red'>" + "" + "<b/>").append("</td>");
					if (treeNumList.get(j) != null && treeNumList.get(j) != 0) {
						Date start = new Date(C._flowerYear - 1900, C._memberPropertyVo.startMonth - 1, C._memberPropertyVo.startDay);
						CalendarUtil.addDaysToDate(start, j * C._memberPropertyVo.interval);
						keyListFull.add(key + "&&" + dtf.format(start));
					}
				}
			}
			chartLog.append("</tr>");

			chartLog.append("<tr><td>").append(flower.tdNull0(flower.block)).append("</td>");
			chartLog.append("<td>").append(flower.tdNull0(flower.subRegion)).append("</td>");
			chartLog.append("<td>").append(flower.tdNull0(flower.tree)).append("</td>");
			chartLog.append("<td>").append("&nbsp;").append("</td>");
			for (int j = 0; j < C._memberPropertyVo.columns; j++) {
				if (j < treeNumList.size()) {
					//if (treeNumList.get(j) == 0) chartLog.append("<td>").append("<b style='color:red'>" + "&nbsp" + "<b/>").append("</td>");
					//else 
					chartLog.append("<td>").append("<b style='color:red'>" + flower.tdNull0(treeNumList.get(j)) + "<b/>").append("</td>");
				}
			}
			chartLog.append("</tr>");
			i++;
		}
		chartLog.append("</table>");

		//Map<String, LookupTVo> lookupTMap = this.getLookupTMap(keyList);
		Map<String, Date> harvestMap = this.getHarvestMap(keyListFull);
		Map<String, Integer> treeMap = new HashMap<String, Integer>();
		Map<String, Integer> regionTreeMap = new HashMap<String, Integer>();
		Map<String, Integer> varietyTreeMap = new HashMap<String, Integer>();
		Map<String, Integer> combinedTreeMap = new HashMap<String, Integer>();

		Map<String, Integer> regionTotalMap = new HashMap<String, Integer>();
		Map<String, Integer> varietyTotalMap = new HashMap<String, Integer>();
		Map<String, Integer> combinedTotalMap = new HashMap<String, Integer>();

		for (String key : keyList) {
			FlowerVo flower = flowerMap.get(key);
			String arr[] = key.split("&&");
			String regionId = arr[0];
			String varietyId = arr[1];

			List<Integer> treeNumList = flower.getTreeNumList();
			for (int j = 0; j < C._memberPropertyVo.columns; j++) {
				if (j < treeNumList.size()) {
					if (treeNumList.get(j) != null && treeNumList.get(j) != 0) {
						Date start = new Date(C._flowerYear - 1900, C._memberPropertyVo.startMonth - 1, C._memberPropertyVo.startDay);
						CalendarUtil.addDaysToDate(start, j * C._memberPropertyVo.interval);

						String keyFull = key + "&&" + dtf.format(start);
						Date harvestDate = harvestMap.get(keyFull);
						keyFull = key + "&&" + dtf.format(harvestDate);
						Integer tree = treeMap.get(keyFull);
						if (tree == null) tree = 0;
						tree += treeNumList.get(j);
						treeMap.put(keyFull, tree);

						keyFull = regionId + "&&" + dtf.format(start);
						keyFull = regionId + "&&" + dtf.format(harvestDate);
						tree = regionTreeMap.get(keyFull);
						if (tree == null) tree = 0;
						tree += treeNumList.get(j);
						regionTreeMap.put(keyFull, tree);

						keyFull = varietyId + "&&" + dtf.format(start);
						keyFull = varietyId + "&&" + dtf.format(harvestDate);
						tree = varietyTreeMap.get(keyFull);
						if (tree == null) tree = 0;
						tree += treeNumList.get(j);
						varietyTreeMap.put(keyFull, tree);

						keyFull = dtf.format(start);
						keyFull = dtf.format(harvestDate);
						tree = combinedTreeMap.get(keyFull);
						if (tree == null) tree = 0;
						tree += treeNumList.get(j);
						combinedTreeMap.put(keyFull, tree);

						keyFull = regionId;
						Integer total = regionTotalMap.get(keyFull);
						if (total == null) total = 0;
						total += treeNumList.get(j);
						regionTotalMap.put(keyFull, total);

						keyFull = varietyId;
						total = varietyTotalMap.get(keyFull);
						if (total == null) total = 0;
						total += treeNumList.get(j);
						varietyTotalMap.put(keyFull, total);

						keyFull = "combined";
						total = combinedTotalMap.get(keyFull);
						if (total == null) total = 0;
						total += treeNumList.get(j);
						combinedTotalMap.put(keyFull, total);
					}
				}
			}
		}

		chartLog.append("<table border=0 cellspacing=0>");
		chartLog.append("<tr><td style='width:80'><b><u>region</u></b></td>");
		chartLog.append("<td style='width:100'><b><u>variety</u></b></td>");
		chartLog.append("<td style='width:100'><b><u>harvestDate</u></b></td>");
		chartLog.append("<td style='width:100'><b><u>tree</u></b></td></tr>");

		List<String> treeKeyList = new ArrayList<String>(treeMap.keySet());
		Collections.sort(treeKeyList);

		for (String key : treeKeyList) {
			String arr[] = key.split("&&");
			String regionId = arr[0];
			String varietyId = arr[1];
			Date harvestDate = null;
			try {
				harvestDate = dtf.parse(arr[2]);
			} catch (ParseException e) {
			}
			Integer tree = treeMap.get(key);

			chartLog.append("<tr>");
			chartLog.append("<td>").append(regionMap.get(regionId)).append("</td>");
			chartLog.append("<td>").append(varietyMap.get(varietyId)).append("</td>");
			chartLog.append("<td>").append(arr[2]).append("</td>");
			chartLog.append("<td>").append(tree).append("</td>");
			chartLog.append("</tr>");
		}
		chartLog.append("<tr>");
		chartLog.append("<td>").append("&nbsp;").append("</td>");
		chartLog.append("<td>").append("&nbsp;").append("</td>");
		chartLog.append("<td>").append("&nbsp;").append("</td>");
		chartLog.append("<td><b style='color:red'>").append(combinedTotalMap.get("combined")).append("</b></td>");
		chartLog.append("<td>").append("&nbsp;").append("</td>");
		chartLog.append("</tr>");
		chartLog.append("</table>");

		chartLog.append("<table border=0 cellspacing=0>");
		chartLog.append("<tr><td style='width:80'><b><u>region</u></b></td>");
		chartLog.append("<td style='width:100'><b><u>harvestDate</u></b></td>");
		chartLog.append("<td style='width:100'><b><u>tree</u></b></td>");
		chartLog.append("<td style='width:100'><b><u>total</u></b></td>");
		chartLog.append("<td style='width:100'><b><u>percent</u></b></td></tr>");

		treeKeyList = new ArrayList<String>(regionTreeMap.keySet());
		Collections.sort(treeKeyList);

		for (String key : treeKeyList) {
			String arr[] = key.split("&&");
			String regionId = arr[0];
			Date harvestDate = null;
			try {
				harvestDate = dtf.parse(arr[1]);
			} catch (ParseException e) {
			}
			Integer total = regionTotalMap.get(regionId);
			Integer tree = regionTreeMap.get(key);
			Integer percent = (int) Math.round(100 * (1.0 * tree / total));
			regionTreeMap.put(key, percent);

			chartLog.append("<tr>");
			chartLog.append("<td>").append(regionMap.get(regionId)).append("</td>");
			chartLog.append("<td>").append(arr[1]).append("</td>");
			chartLog.append("<td>").append(tree).append("</td>");
			chartLog.append("<td>").append(total).append("</td>");
			chartLog.append("<td>").append(percent).append("</td>");
			chartLog.append("</tr>");
		}
		chartLog.append("</table>");

		chartLog.append("<table border=0 cellspacing=0>");
		chartLog.append("<tr><td style='width:80'><b><u>region</u></b></td>");
		chartLog.append("<td style='width:100'><b><u>tree</u></b></td></tr>");

		treeKeyList = new ArrayList<String>(regionTotalMap.keySet());
		Collections.sort(treeKeyList);

		for (String key : treeKeyList) {
			Integer tree = regionTotalMap.get(key);
			chartLog.append("<tr>");
			chartLog.append("<td>").append(regionMap.get(key)).append("</td>");
			chartLog.append("<td>").append(tree).append("</td>");
			chartLog.append("</tr>");
		}
		chartLog.append("<tr>");
		chartLog.append("<td>").append("<b style='color:red'>combined</b>").append("</td>");
		chartLog.append("<td><b style='color:red'>").append(combinedTotalMap.get("combined")).append("</b></td>");
		chartLog.append("</tr>");
		chartLog.append("</table>");

		chartLog.append("<table border=0 cellspacing=0>");
		chartLog.append("<tr><td style='width:80'><b><u>variety</u></b></td>");
		chartLog.append("<td style='width:100'><b><u>harvestDate</u></b></td>");
		chartLog.append("<td style='width:100'><b><u>tree</u></b></td>");
		chartLog.append("<td style='width:100'><b><u>total</u></b></td>");
		chartLog.append("<td style='width:100'><b><u>percent</u></b></td></tr>");

		treeKeyList = new ArrayList<String>(varietyTreeMap.keySet());
		Collections.sort(treeKeyList);

		for (String key : treeKeyList) {
			String arr[] = key.split("&&");
			String varietyId = arr[0];
			Date harvestDate = null;
			try {
				harvestDate = dtf.parse(arr[1]);
			} catch (ParseException e) {
			}
			Integer total = varietyTotalMap.get(varietyId);
			Integer tree = varietyTreeMap.get(key);
			Integer percent = (int) Math.round(100 * (1.0 * tree / total));
			varietyTreeMap.put(key, percent);

			chartLog.append("<tr>");
			chartLog.append("<td>").append(varietyMap.get(varietyId)).append("</td>");
			chartLog.append("<td>").append(arr[1]).append("</td>");
			chartLog.append("<td>").append(tree).append("</td>");
			chartLog.append("<td>").append(total).append("</td>");
			chartLog.append("<td>").append(percent).append("</td>");
			chartLog.append("</tr>");
		}
		chartLog.append("</table>");

		chartLog.append("<table border=0 cellspacing=0>");
		chartLog.append("<tr><td style='width:80'><b><u>variety</u></b></td>");
		chartLog.append("<td style='width:100'><b><u>tree</u></b></td></tr>");

		treeKeyList = new ArrayList<String>(varietyTotalMap.keySet());
		Collections.sort(treeKeyList);

		for (String key : treeKeyList) {
			Integer tree = varietyTotalMap.get(key);
			chartLog.append("<tr>");
			chartLog.append("<td>").append(varietyMap.get(key)).append("</td>");
			chartLog.append("<td>").append(tree).append("</td>");
			chartLog.append("</tr>");
		}
		chartLog.append("<tr>");
		chartLog.append("<td>").append("<b style='color:red'>combined</b>").append("</td>");
		chartLog.append("<td><b style='color:red'>").append(combinedTotalMap.get("combined")).append("</b></td>");
		chartLog.append("</tr>");
		chartLog.append("</table>");

		chartLog.append("<table border=0 cellspacing=0>");
		chartLog.append("<td style='width:100'><b><u>harvestDate</u></b></td>");
		chartLog.append("<td style='width:100'><b><u>tree</u></b></td>");
		chartLog.append("<td style='width:100'><b><u>total</u></b></td>");
		chartLog.append("<td style='width:100'><b><u>percent</u></b></td></tr>");

		treeKeyList = new ArrayList<String>(combinedTreeMap.keySet());
		Collections.sort(treeKeyList);

		for (String key : treeKeyList) {
			String arr[] = key.split("&&");
			Date harvestDate = null;
			try {
				harvestDate = dtf.parse(arr[0]);
			} catch (ParseException e) {
			}
			Integer total = combinedTotalMap.get("combined");
			Integer tree = combinedTreeMap.get(key);
			Integer percent = (int) Math.round(100 * (1.0 * tree / total));
			combinedTreeMap.put(key, percent);

			chartLog.append("<tr>");
			chartLog.append("<td>").append(arr[0]).append("</td>");
			chartLog.append("<td>").append(tree).append("</td>");
			chartLog.append("<td>").append(total).append("</td>");
			chartLog.append("<td>").append(percent).append("</td>");
			chartLog.append("</tr>");
		}
		chartLog.append("</table>");

		Map<String, Map<String, FlowerChartVo>> flowerChartMap = new HashMap<String, Map<String, FlowerChartVo>>();
		Map<String, FlowerChartVo> regionChartMap = new HashMap<String, FlowerChartVo>();
		Map<String, FlowerChartVo> varietyChartMap = new HashMap<String, FlowerChartVo>();
		flowerChartMap.put("region", regionChartMap);
		flowerChartMap.put("variety", varietyChartMap);

		for (String key : regionTreeMap.keySet()) {
			String arr[] = key.split("&&");
			String regionId = arr[0];
			Date harvestDate = null;
			try {
				harvestDate = dtf.parse(arr[1]);
			} catch (ParseException e) {
			}
			Integer percent = regionTreeMap.get(key);

			FlowerChartVo flowerChart = regionChartMap.get(regionId);
			if (flowerChart == null) {
				flowerChart = new FlowerChartVo();
				regionChartMap.put(regionId, flowerChart);
			}
			flowerChart.name = regionMap.get(regionId);
			flowerChart.tree = regionTotalMap.get(regionId);
			XYDateDoubleVo xy = new XYDateDoubleVo();
			xy.x = harvestDate;
			xy.y = 1.0 * percent;
			flowerChart.xyList.add(xy);
		}

		for (String key : varietyTreeMap.keySet()) {
			String arr[] = key.split("&&");
			String varietyId = arr[0];
			Date harvestDate = null;
			try {
				harvestDate = dtf.parse(arr[1]);
			} catch (ParseException e) {
			}
			Integer percent = varietyTreeMap.get(key);

			FlowerChartVo flowerChart = varietyChartMap.get(varietyId);
			if (flowerChart == null) {
				flowerChart = new FlowerChartVo();
				varietyChartMap.put(varietyId, flowerChart);
			}
			flowerChart.name = varietyMap.get(varietyId);
			flowerChart.tree = varietyTotalMap.get(varietyId);
			XYDateDoubleVo xy = new XYDateDoubleVo();
			xy.x = harvestDate;
			xy.y = 1.0 * percent;
			flowerChart.xyList.add(xy);
		}

		for (String key : combinedTreeMap.keySet()) {
			String arr[] = key.split("&&");
			String combinedId = "combined";
			Date harvestDate = null;
			try {
				harvestDate = dtf.parse(arr[0]);
			} catch (ParseException e) {
			}
			Integer percent = combinedTreeMap.get(key);

			FlowerChartVo flowerChart = regionChartMap.get(combinedId);
			if (flowerChart == null) {
				flowerChart = new FlowerChartVo();
				regionChartMap.put(combinedId, flowerChart);
				varietyChartMap.put(combinedId, flowerChart);
			}

			flowerChart.name = combinedId;
			flowerChart.tree = combinedTotalMap.get(combinedId);
			XYDateDoubleVo xy = new XYDateDoubleVo();
			xy.x = harvestDate;
			xy.y = 1.0 * percent;
			flowerChart.xyList.add(xy);
		}

		for (String regionId : regionChartMap.keySet()) {
			Collections.sort(regionChartMap.get(regionId).xyList, new Comparator<XYDateDoubleVo>() {

				public int compare(XYDateDoubleVo o1, XYDateDoubleVo o2) {
					return o1.x.compareTo(o2.x);
				}
			});
		}

		for (String varietyId : varietyChartMap.keySet()) {
			Collections.sort(varietyChartMap.get(varietyId).xyList, new Comparator<XYDateDoubleVo>() {

				public int compare(XYDateDoubleVo o1, XYDateDoubleVo o2) {
					return o1.x.compareTo(o2.x);
				}
			});
		}

		log.saveFile(chartLog.toString());
		return flowerChartMap;
	}

	public List<FlowerChartVo> viewFlowerChart2(List<String> regionIdList) {
		List<FlowerChartVo> flowerChartList = new ArrayList<FlowerChartVo>();
		FlowerChartVo totalChartVo = new FlowerChartVo();
		totalChartVo.name = "Region Group";
		flowerChartList.add(totalChartVo);
		Map<String, Double> totalMap = new HashMap<String, Double>();
		List<String> dateList2 = null;
		for (int i = 0; i < regionIdList.size(); i++) {
			FlowerChartVo flowerChartVo = new FlowerChartVo();
			flowerChartVo.name = regionIdList.get(i);
			flowerChartVo.tree = 0;

			List<FlowerVo> flowerList = this.getFlowerListByRegionId(regionIdList.get(i));
			Map<String, Double> varietyMap = new HashMap<String, Double>();
			Map<String, Double> regionMap = new HashMap<String, Double>();
			List<String> dateList = null;
			for (int j = 0; j < flowerList.size(); j++) {
				FlowerVo flower = flowerList.get(j);
				if (dateList == null) dateList = flower.getStringList(flower.dateList);
				if (dateList2 == null) dateList2 = dateList;
				List<String> percentList = flower.getStringList(flower.percentList);
				if (percentList.size() == 0) continue;
				boolean hasData = false;
				Double prePercent = 0.0;
				for (int k = 0; k < dateList.size(); k++) {
					String date = dateList.get(k);
					Double percent = prePercent;
					if (!"".equals(percentList.get(k))) {
						hasData = true;
						try {
							percent = Double.parseDouble(percentList.get(k));
						} catch (Exception e) {
						}
					}

					String key = flower.varietyId + "__" + date;

					if (varietyMap.get(key) == null) varietyMap.put(key, 0.0);
					Double tree = varietyMap.get(key);
					tree += 0.01 * (percent - prePercent) * flower.tree;
					varietyMap.put(key, tree);

					if (regionMap.get(date) == null) regionMap.put(date, 0.0);
					tree = regionMap.get(date);
					tree += 0.01 * (percent - prePercent) * flower.tree;
					regionMap.put(date, tree);

					if (totalMap.get(date) == null) totalMap.put(date, 0.0);
					tree = totalMap.get(date);
					tree += 0.01 * (percent - prePercent) * flower.tree;
					totalMap.put(date, tree);

					prePercent = percent;
				}
				if (hasData == true) {
					flowerChartVo.tree += flower.tree;
					totalChartVo.tree += flower.tree;
				}
			}
			if (dateList != null) {
				Double totalTree = 0.0;
				for (int k = 0; k < dateList.size(); k++) {
					String date = dateList.get(k);
					totalTree += regionMap.get(date);
				}
				for (int k = 0; k < dateList.size(); k++) {
					String date = dateList.get(k);
					XYDateDoubleVo xy = new XYDateDoubleVo();
					//xy.x = date;
					xy.y = 100 * regionMap.get(date) / totalTree;
					flowerChartVo.xyList.add(xy);
				}
			}
			flowerChartList.add(flowerChartVo);
		}
		if (dateList2 != null) {
			Double totalTree = 0.0;
			for (int k = 0; k < dateList2.size(); k++) {
				String date = dateList2.get(k);
				totalTree += totalMap.get(date);
			}
			for (int k = 0; k < dateList2.size(); k++) {
				String date = dateList2.get(k);
				XYDateDoubleVo xy = new XYDateDoubleVo();
				//xy.x = date;
				xy.y = 100 * totalMap.get(date) / totalTree;
				totalChartVo.xyList.add(xy);
			}
		}
		return flowerChartList;
	}

	public String viewTemperatureSave(TemperatureUrlVo temperatureUrlVo) {
		StringBuffer log = new StringBuffer();
		this.saveTemperatureUrlVoMap(temperatureUrlVo);
		Map<Date, TemperatureVo> temperatureMap = new HashMap<Date, TemperatureVo>();
		String header = "";
		try {
			Document doc = Jsoup.connect(temperatureUrlVo.minUrl).get();
			Element div = doc.getElementById("content-block");
			header += "<b style='color:red'>" + div.child(0).text() + " " + div.child(1).text() + "</b><br/>";

			Element table = doc.getElementById("dataTable");
			Elements trs = table.getElementsByTag("tr");
			int year = 1900;
			int month = 1;
			int day = 1;
			int i = 0;
			for (Element tr : trs) {
				Elements tds = tr.children();
				int j = 0;
				for (Element td : tds) {
					String str = td.text();
					if (j == 0) {
						if (i == 0) year = Integer.parseInt(str);
						if (i >= 2 && i <= 32) day = i - 1;
					} else {
						if (i >= 2 && i <= 32) {
							try {
								Double minT = Double.parseDouble(str);
								month = j;
								Date date = new Date(year - 1900, month - 1, day);
								TemperatureVo temperatureVo = temperatureMap.get(date);
								if (temperatureVo == null) {
									temperatureVo = new TemperatureVo();
									temperatureMap.put(date, temperatureVo);
								}
								temperatureVo.regionId = temperatureUrlVo.regionId;
								temperatureVo.dateT = date;
								temperatureVo.minT = minT;
							} catch (Exception ex) {
							}
						}
					}
					j++;
				}
				i++;
			}

			doc = Jsoup.connect(temperatureUrlVo.maxUrl).get();
			div = doc.getElementById("content-block");
			header += "<b style='color:red'>" + div.child(0).text() + " " + div.child(1).text() + "</b><br/>";

			table = doc.getElementById("dataTable");
			trs = table.getElementsByTag("tr");
			year = 1900;
			month = 1;
			day = 1;
			i = 0;
			for (Element tr : trs) {
				Elements tds = tr.children();
				int j = 0;
				for (Element td : tds) {
					String str = td.text();
					if (j == 0) {
						if (i == 0) year = Integer.parseInt(str);
						if (i >= 2 && i <= 32) day = i - 1;
					} else {
						if (i >= 2 && i <= 32) {
							try {
								Double maxT = Double.parseDouble(str);
								month = j;
								Date date = new Date(year - 1900, month - 1, day);
								TemperatureVo temperatureVo = temperatureMap.get(date);
								if (temperatureVo == null) {
									temperatureVo = new TemperatureVo();
									temperatureMap.put(date, temperatureVo);
								}
								temperatureVo.regionId = temperatureUrlVo.regionId;
								temperatureVo.dateT = date;
								temperatureVo.maxT = maxT;
							} catch (Exception ex) {
							}
						}
					}
					j++;
				}
				i++;
			}

			log.append(header);
			log.append("<table border=1>");
			log.append("<tr><td style='width:150'><b><u>regionId</u></b></td>");
			log.append("<td style='width:100'><b><u>dateT</u></b></td>");
			log.append("<td style='width:100'><b><u>minT</u></b></td>");
			log.append("<td style='width:100'><b><u>maxT</u></b></td></tr>");

			DateFormat dateFormat = new SimpleDateFormat("dd-MMM-yyyy");
			List<Date> keyList = new ArrayList<Date>(temperatureMap.keySet());
			Collections.sort(keyList);
			for (Date date : keyList) {
				TemperatureVo temperatureVo = temperatureMap.get(date);
				if (temperatureVo.minT != null && temperatureVo.maxT != null) {
					this.saveTemperature(temperatureVo);
				}
				log.append("<tr>");
				log.append("<td>").append(temperatureVo.regionId).append("</td>");
				log.append("<td>").append(dateFormat.format(temperatureVo.dateT)).append("</td>");
				log.append("<td>").append(temperatureVo.minT).append("</td>");
				log.append("<td>").append(temperatureVo.maxT).append("</td>");
				log.append("</tr>");
			}
			log.append("</table>");
		} catch (IOException e) {
			e.printStackTrace();
		}
		return log.toString();
	}

	public MemberPropertyVo viewMemberPropertyVo() {
		MemberPropertyVo memberPropertyVo = (MemberPropertyVo) this.readObject("WEB-INF/memberPropertyVo.data");
		if (memberPropertyVo == null) memberPropertyVo = new MemberPropertyVo();
		return memberPropertyVo;
	}

	public MemberPropertyVo saveMemberPropertyVo(MemberPropertyVo memberPropertyVo) {
		this.writeObject("WEB-INF/memberPropertyVo.data", memberPropertyVo);
		return memberPropertyVo;
	}

	/*
		public String viewOrchardEmailString() {
			Log log = Log.get(this.getFilePath("WEB-INF/orchardEmail.string"));
			return log.loadFile();
		}

		public String saveOrchardEmailString(String string) {
			Log log = Log.get(this.getFilePath("WEB-INF/orchardEmail.string"));
			return log.saveFile(string);
		}
	*/
	//public static List<EmailVo> emailVoList;

	public List<EmailVo> viewEmailVoList() {
		/*
		if (S._emailVoList == null) return new ArrayList<EmailVo>();
		
		if (S._emailVoList == null) {
			S.emailVoList = new ArrayList<EmailVo>();
			S._emailVoList = Collections.synchronizedList(S.emailVoList);
			S.memberMap = this.getMemberMap();
			S.contactMap = this.getContactMap();
			S.orchardMap = this.getOrchardMap();

			for (String orchardId : S.orchardMap.keySet()) {
				OrchardVo orchardVo = S.orchardMap.get(orchardId);
				for (String contactId : orchardVo.getStringList(orchardVo.emailContactId)) {
					ContactVo contactVo = S.contactMap.get(contactId);
					if (contactVo == null || contactVo.memberId == null) continue;
					MemberVo memberVo = S.memberMap.get(contactVo.memberId + "");
					EmailVo emailVo = new EmailVo();

					emailVo.memberId = memberVo.memberId + "";
					emailVo.contactId = contactVo.contactId + "";
					emailVo.orchardId = orchardVo.orchardId + "";

					emailVo.memberHeader = memberVo.businessName;
					emailVo.contactHeader = contactVo.getCaption();
					emailVo.orchardHeader = orchardVo.getLocation();

					//emailVo.email = contactVo.email;
					if (!"".equals(contactVo.email)) emailVo.email = "mangomail001@yahoo.com";
					else emailVo.email = "";

					emailVo.status = "";
					S._emailVoList.add(emailVo);
				}
			}
		}
		return S.emailVoList;
		*/
		return null;
	}

	/*
	public List<EmailVo> __viewEmailVoListReload(MemberVo memberSearchVo) {
		S._emailVoList = null;
		if (this.emailThreadList != null) for (int i = 0; i < this.emailThreadList.size(); i++) {
			EmailThread emailThread = this.emailThreadList.get(i);
			emailThread.done = true;
		}

		S.emailVoList = new ArrayList<EmailVo>();
		S._emailVoList = Collections.synchronizedList(S.emailVoList);
		S.memberMap = this.getMemberMap();
		S.contactMap = this.getContactMap();

		for (String orchardId : S.orchardMap.keySet()) {
			OrchardVo orchardVo = S.orchardMap.get(orchardId);
			for (String contactId : orchardVo.getStringList(orchardVo.emailContactId)) {
				ContactVo contactVo = S.contactMap.get(contactId);
				if (contactVo == null || contactVo.memberId == null) continue;
				if (!memberSearchVo.memberIdList.contains(contactVo.memberId + "")) continue;

				MemberVo memberVo = S.memberMap.get(contactVo.memberId + "");
				EmailVo emailVo = new EmailVo();

				emailVo.memberId = memberVo.memberId + "";
				emailVo.contactId = contactVo.contactId + "";
				emailVo.orchardId = orchardVo.orchardId + "";

				emailVo.memberHeader = memberVo.businessName;
				emailVo.contactHeader = contactVo.getCaption();
				emailVo.orchardHeader = orchardVo.getLocation();

				//emailVo.email = contactVo.email;
				if (!"".equals(contactVo.email)) emailVo.email = "no_reply@mangoes.net.au";//contactVo.email
				else emailVo.email = "";
				emailVo.statusEmail = "";

				if (!"".equals(contactVo.fax)) emailVo.fax = "0384144015";//contactVo.fax;
				else emailVo.fax = "";
				emailVo.statusFax = "";

				if (!"".equals(contactVo.mobile)) emailVo.sms = "61400808689";//contactVo.mobile
				else emailVo.sms = "";
				emailVo.statusSms = "";

				S._emailVoList.add(emailVo);
			}
		}

		return S.emailVoList;

		//return viewEmailVoList();
	}
	*/
	public List<EmailVo> viewEmailVoListReloadFull(List<String> memberIdList) {
		ArrayList<EmailVo> emailVoList = new ArrayList<EmailVo>();
		Map<String, MemberVo> memberMap = this.getMemberMap();
		Map<String, ContactVo> contactMap = this.getContactMap();
		//S.orchardMap = this.getOrchardMap();
		Map<String, List<OrchardVo>> orchardListMap = this.getOrchardListMap();

		if (memberIdList == null) memberIdList = new ArrayList<String>(orchardListMap.keySet());
		Collections.sort(memberIdList);
		Collections.reverse(memberIdList);

		C._mailCode = 0;
		for (int i = 0; i < memberIdList.size(); i++) {
			String memberId = memberIdList.get(i);
			List<OrchardVo> orchardList = orchardListMap.get(memberId);
			if (orchardList == null) continue;
			for (int j = 0; j < orchardList.size(); j++) {
				OrchardVo orchardVo = orchardList.get(j);
				if ("suspended".equals(orchardVo.getStatus())) continue;
				for (String contactId : orchardVo.getStringList(orchardVo.emailContactId)) {
					ContactVo contactVo = contactMap.get(contactId);
					if (contactVo == null || contactVo.memberId == null) continue;
					if ("suspended".equals(contactVo.getStatus())) continue;
					MemberVo memberVo = memberMap.get(contactVo.memberId + "");
					contactVo.memberBusinessName = memberVo.businessName;

					/*
					EmailVo emailVo = new EmailVo();

					emailVo.memberId = memberVo.memberId + "";
					emailVo.contactId = contactVo.contactId + "";
					emailVo.orchardId = orchardVo.orchardId + "";

					emailVo.memberHeader = memberVo.businessName;
					emailVo.contactHeader = contactVo.getCaption();
					emailVo.orchardHeader = orchardVo.getLocation();

					//emailVo.email = contactVo.email;
					if (!"".equals(contactVo.email)) {
						if (mailCode % 3 == 0) emailVo.email = "idm@mangoes.net.au";//"no_reply@mangoes.net.au";//contactVo.email
						if (mailCode % 3 == 1) emailVo.email = "mangomail001@yahoo.com";
						if (mailCode % 3 == 2) emailVo.email = "idm@mangoes.net.au";
						mailCode++;
					} else emailVo.email = "";
					emailVo.statusEmail = "";

					if (!"".equals(contactVo.fax)) emailVo.fax = "0738461966";//"0384144015";//contactVo.fax;
					else emailVo.fax = "";
					emailVo.statusFax = "";

					if (!"".equals(contactVo.mobile)) emailVo.sms = "0400808689";//;"61400808689";//contactVo.mobile
					else emailVo.sms = "";
					emailVo.statusSms = "";
					*/
					EmailVo emailVo = C.getEmailVo(contactVo, orchardVo);

					emailVoList.add(emailVo);
				}
			}
		}

		return emailVoList;

		//return viewEmailVoList();
	}

	public List<EmailVo> viewEmailVoListReload(String type) {
		ArrayList<EmailVo> emailVoList = new ArrayList<EmailVo>();
		Map<String, MemberVo> memberMap = this.getMemberMap();

		List<ContactVo> contactList;
		if ("search".equals(type)) {
			contactList = (List<ContactVo>) this.perThreadRequest.get().getSession().getAttribute("searchContactList");
		} else {
			contactList = this.getContactList();
		}

		C._mailCode = 0;
		for (int i = 0; i < contactList.size(); i++) {
			ContactVo contactVo = contactList.get(i);
			if ("email".equals(type) && !contactVo.isServiceEmail()) continue;
			if ("fax".equals(type) && !contactVo.isServiceFax()) continue;
			if ("sms".equals(type) && !contactVo.isServiceSms()) continue;

			if ("amia".equals(type) && !contactVo.isServiceAmia()) continue;
			if ("workshops".equals(type) && !contactVo.isServiceWorkshops()) continue;

			MemberVo memberVo = memberMap.get(contactVo.memberId + "");
			if (memberVo != null) contactVo.memberBusinessName = memberVo.businessName;
			EmailVo emailVo = C.getEmailVo(contactVo);
			emailVoList.add(emailVo);
		}
		return emailVoList;
	}

	public List<EmailThread> emailThreadList;

	public void viewEmailVoListSend(int emailIndex) {
		MemberPropertyVo memberPropertyVo = this.viewMemberPropertyVo();

		EmailContentVo emailContentVo = this.viewEmailContentVoList().get(emailIndex);
		String subject = emailContentVo.subject;
		String content = emailContentVo.content;
		this.emailThreadList = new ArrayList<EmailThread>();

		EmailThread emailThread = new EmailThread();
		emailThread.parent = this;
		emailThread.STMPserver = memberPropertyVo.STMPserver;
		emailThread.email = memberPropertyVo.email;
		emailThread.account = memberPropertyVo.account;
		emailThread.pass = memberPropertyVo.pass;
		emailThread.setProperties();
		emailThread.orchardEmailSubject = subject;
		emailThread.orchardEmailContent = content;
		this.emailThreadList.add(emailThread);

		emailThread = new EmailThread();
		emailThread.parent = this;
		emailThread.STMPserver = memberPropertyVo.STMPserver;
		emailThread.email = memberPropertyVo.email;
		emailThread.account = memberPropertyVo.account;
		emailThread.pass = memberPropertyVo.pass;
		emailThread.setProperties();
		emailThread.orchardEmailSubject = subject;
		emailThread.orchardEmailContent = content;
		this.emailThreadList.add(emailThread);

		emailThread = new EmailThread();
		emailThread.parent = this;
		emailThread.STMPserver = memberPropertyVo.STMPserver;
		emailThread.email = memberPropertyVo.email;
		emailThread.account = memberPropertyVo.account;
		emailThread.pass = memberPropertyVo.pass;
		emailThread.setProperties();
		emailThread.orchardEmailSubject = subject;
		emailThread.orchardEmailContent = content;
		this.emailThreadList.add(emailThread);
		//}
		for (int i = 0; i < this.emailThreadList.size(); i++) {
			emailThread = this.emailThreadList.get(i);
			emailThread.start();
		}

	}

	public EmailVo viewEmailVoSend(EmailVo emailVo, int emailIndex, int smsIndex) {
		long start = System.currentTimeMillis();
		EmailContentVo emailContentVo = this.viewEmailContentVoList().get(emailIndex);
		SmsContentVo smsContentVo = this.viewSmsContentVoList().get(smsIndex);

		while (1 == 1) {

			final MemberPropertyVo memberPropertyVo = this.viewMemberPropertyVo();
			Integer port = 587;
			boolean starttls = false;

			Properties properties = System.getProperties();
			properties.setProperty("mail.smtp.host", memberPropertyVo.STMPserver);
			properties.setProperty("mail.smtp.auth", "true");
			properties.setProperty("mail.smtp.connectiontimeout", "20000");
			properties.setProperty("mail.smtp.timeout", "20000");
			properties.setProperty("mail.smtp.port", port.toString());
			if (starttls == true) properties.setProperty("mail.smtp.starttls.enable", "true");

			Session session = Session.getInstance(properties, new javax.mail.Authenticator() {
				protected PasswordAuthentication getPasswordAuthentication() {
					return new PasswordAuthentication(memberPropertyVo.account, memberPropertyVo.pass);
				}
			});

			if ("".equals(emailVo.email.trim())) emailVo.statusEmail = "skip";
			if ("".equals(emailVo.fax.trim())) emailVo.statusFax = "skip";
			if ("".equals(emailVo.sms.trim())) emailVo.statusSms = "skip";

			if (!"sent".equals(emailVo.statusEmail) && !"skip".equals(emailVo.statusEmail)) {
				try {

					String to = emailVo.email;
					MimeMessage message = new MimeMessage(session);
					message.setFrom(new InternetAddress(memberPropertyVo.email));
					message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));

					MemberVo member = this.getMember(emailVo.memberId + "");//S.memberMap.get(emailVo.memberId);
					ContactVo contact = this.getContact(emailVo.contactId + "");//S.contactMap.get(emailVo.contactId);
					OrchardVo orchard = this.getOrchard(emailVo.orchardId + "");//S.orchardMap.get(emailVo.orchardId);

					message.setSubject(C.templateToString(emailContentVo.subject, member, contact, orchard));
					message.setContent(C.templateToString(emailContentVo.content, member, contact, orchard), "text/html");
					Transport.send(message);
					emailVo.statusEmail = "sent";
				} catch (Exception ex) {
					ex.printStackTrace();
					emailVo.statusEmail = "resend";
				}
			}

			if (!"sent".equals(emailVo.statusFax) && !"skip".equals(emailVo.statusFax)) {
				try {

					String to = emailVo.fax.trim() + "@send.gofax.com.au";
					MimeMessage message = new MimeMessage(session);
					message.setFrom(new InternetAddress(memberPropertyVo.email));
					message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
					//message.addRecipient(Message.RecipientType.BCC, new InternetAddress(emailVo.email));

					//MemberVo member = S.memberMap.get(emailVo.memberId);
					//ContactVo contact = S.contactMap.get(emailVo.contactId);
					//OrchardVo orchard = S.orchardMap.get(emailVo.orchardId);
					MemberVo member = this.getMember(emailVo.memberId + "");//S.memberMap.get(emailVo.memberId);
					ContactVo contact = this.getContact(emailVo.contactId + "");//S.contactMap.get(emailVo.contactId);
					OrchardVo orchard = this.getOrchard(emailVo.orchardId + "");//S.orchardMap.get(emailVo.orchardId);

					message.setSubject("/b /hq");
					message.setContent(C.templateToString(emailContentVo.content, member, contact, orchard), "text/html");
					Transport.send(message);
					emailVo.statusFax = "sent";
				} catch (Exception ex) {
					ex.printStackTrace();
					emailVo.statusFax = "resend";
				}
			}

			if (!"sent".equals(emailVo.statusSms) && !"skip".equals(emailVo.statusSms)) {
				String str = "";
				try {
					String query = "http://api.infobip.com/api/v2/sendsms/plain?username=mango2&password=mango123&sender=Friend&smstext=" + URLEncoder.encode(smsContentVo.content, "UTF-8") + "&GSM=" + URLEncoder.encode(emailVo.sms, "UTF-8");
					System.out.println(query);
					//String queryString = "XML=" + URLEncoder.encode(xml, "UTF-8");
					//URL url = new URL("http://api.infobip.com/api/v2/sendsms/xml");
					URL url = new URL(query);
					HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
					//httpCon.setDoOutput(true);
					//httpCon.setRequestMethod("POST");
					//OutputStreamWriter out = new OutputStreamWriter(httpCon.getOutputStream());
					//out.write(queryString);
					//out.flush();

					BufferedReader in = new BufferedReader(new InputStreamReader(httpCon.getInputStream()));
					String line = null;
					while ((line = in.readLine()) != null) {
						str += line;
					}
					//out.close();
					in.close();
					emailVo.statusSms = "sent";
				} catch (Exception ex) {
					ex.printStackTrace();
					emailVo.statusSms = "resend";
				}
			}

			emailVo.attempt++;
			if (emailVo.attempt > 3) {
				if (!"sent".equals(emailVo.statusEmail)) emailVo.statusEmail = "skip";
				if (!"sent".equals(emailVo.statusFax)) emailVo.statusFax = "skip";
				if (!"sent".equals(emailVo.statusSms)) emailVo.statusSms = "skip";
				break;
			}

			if (("sent".equals(emailVo.statusEmail) || "skip".equals(emailVo.statusEmail)) && ("sent".equals(emailVo.statusFax) || "skip".equals(emailVo.statusFax)) && ("sent".equals(emailVo.statusSms) || "skip".equals(emailVo.statusSms))) {
				break;
			}
		}
		long end = System.currentTimeMillis();
		emailVo.time += (int) (end - start) / 1000;
		return emailVo;
	}

	/////////////////////////////Test SMS/Fax
	public String sendSMS(String number, String msg) {
		/*
		String xml = "<SMS>"
		+ "<authentication>"
		+"<username>mango2</username>"
		+"<password>mango123</password>"
		+"</authentication>"
		+"<message>"
		+"<sender>Friend</sender>"
		+"<text>"+msg+"</text>"
		+"<recipients>"
		+"<gsm>"+number+"</gsm>"
		+"</recipients>"
		+"</message>"
		+"</SMS>";
		*/
		String str = "";
		try {
			String query = "http://api.infobip.com/api/v2/sendsms/plain?username=mango2&password=mango123&sender=Friend&smstext=" + URLEncoder.encode(msg, "UTF-8") + "&GSM=" + URLEncoder.encode(number, "UTF-8");
			System.out.println(query);
			//String queryString = "XML=" + URLEncoder.encode(xml, "UTF-8");
			//URL url = new URL("http://api.infobip.com/api/v2/sendsms/xml");
			URL url = new URL(query);
			HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
			//httpCon.setDoOutput(true);
			//httpCon.setRequestMethod("POST");
			//OutputStreamWriter out = new OutputStreamWriter(httpCon.getOutputStream());
			//out.write(queryString);
			//out.flush();

			BufferedReader in = new BufferedReader(new InputStreamReader(httpCon.getInputStream()));
			String line = null;
			while ((line = in.readLine()) != null) {
				str += line;
			}
			//out.close();
			in.close();
		} catch (Exception e) {
		}
		return str;
	}
}
